I have 4 tables in my DB:
Table project_ppi:
id (PRIMARY KEY)
Table scopus_author:
id (PRIMARY KEY),
project_ppi, -> linked to id in table project_ppi
author_scopus_id
Table author_subject_area:
author_id (PRIMARY KEY) -> linked to id in table scopus_author
Table project_author_match:
project_ppi (PRIMARY_KEY),
author_scopus_id (PRIMARY KEY),
match_value
What I need to do:
In practice, given a project (table project_ppi) I need to show all the authors (table scopus_author) linked to this project and for each author show his/her area of working (table author_subject_area) but order the result by match_value (table project_author_match).
I'm able to do it in "normal SQL" statements but I'm stuck in doing it in Yii2 framework.
I have a model for each of these tables in my php but I don't really know where to start.
Can anyone give me a hint?
Thanks in advance!
In short
There are already a handful of guides that can help you, and stating that you use a normal SQL database; like MariaDB or MySQL therefore you ought to use ActiveRecord Models. More of details here (https://www.yiiframework.com/doc/guide/2.0/en/db-active-record)
A bit of details
As you should do, you have models for each table, then in each model you add a method that is preferable to be called "getSomething" and this uses the "hasOne" or "hasMany" relation between tables, then in your Yii query you just use the joinWith('relationName') method will making your query. An example:
$query = Post::find()->joinWith('user')->where(['user.id' => 1]);
And this query will get all posts that were written by user whose ID is 1. Assuming a simple database with 2 tables user, post
Related
I am working on a game where the user can register, has an inventory and has weapons in that inventory. I want to store this information in my database.
Here is how I have set it up so far:
My user table contains a UserID column (along with other information).
My inventory table contains an InventoryID column and a UserID column
(the UserID corresponds to the owner of the inventory)
My Weapons table contains an InventoryID column which references the
Inventory it belongs to.
Is this the standard way of doing things? Can I change my layout and make it simpler? It just seems a little tedious to work with databases like this.
It would be so much easier if my User table had a reference to an inventory entry and that entry had an array of weapons. I've achieved this by storing references to the ID's of each entry but I can't just create a "User" php class (which has a reference to an Inventory object, which has an array of Weapon objects) by running one query to the database.
Maybe there is a framework to achieve this?
What You described is simple one-to-many relationship.
You don't need inventory table.
You need a user table with userID as primary key and use it as a foreign key in weapons table.
With help of joins You can use one query to get all records.
Have you considered a NoSQL database? :)
Relational databases often require "join" tables as you describe. You can probably accomplish this without a join table if user to inventory is 1:1 - and 1 weapon can only belong to 1 inventory/user - just have weapons store a user ID.
I came up with this database design after discussing it with many people over IRC.
In my project, a User aka Member can have many "Teams" & "Projects" on his account and can be part of some "Projects" as well. Moreover, "Teams" can have many "Members" as well including the Member who is creating it.
Now my question is, suppose, a Member wants to create a Project or a Team under his account (later on I want to see all projects created by a specific member), can I do a insert into the using following in PHP?
INSERT INTO projects VALUES(values) WHERE member_id = something
I can get the member_id using the session variable I guess.
Use regular INSERT to create the projects or teams row, then use the ID created there to insert into the projects_members or teams_members. Also settle on plural or singular names for your tables (currently you have team not teams).
Your query would be somethings like this
Insert into
table(columns)
select (columns) from
another_table
where
conditions=.
Just Remember One thing the order and names of columns must match.
If Member wants to create a Project or a Team under his account it will not be possible using current structure.
You need to add one more column created_by on projects and team tables.
The name of "team" table should be "teams".
I've done quit a bit of programming with php/mysql on small scale personal projects. However I'm working on my first commercial app that is going to allow customers or businesses to log in and perform CRUD operations. I feel like a total noob asking this question but I have never had to do this before and cannot find any relevant information on the net.
Basically, I've created this app and have a role based system set up on my data base. The problem that I'm running into is how to separate and fetch data for the relevant businesses or groups.
I can't, for example, set my queries up like this: get all records from example table where user id = user id, because that will only return data for that user and not all of the other users that are related to that business. I need a way to get all records that where created by users of a particular business.
I'm thinking that maybe the business should have an id and I should form my queries like this: get all records from example where business id = business id. But I'm not even sure if that's a good approach.
Is there a best practice or a convention for this sort data storing/fetching and grouping?
Note:Security is a huge issue here because I'm storing legal data.
Also, I'm using the latest version of laravel 4 if that's any relevance.
I would like to hear peoples thoughts on this that have encountered this sort problem before and how they designed there database and queries to only get and store data related to that particular business.
Edit: I like to read and learn but cannot find any useful information on this topic - maybe I'm not using the correct search terms. So If you know of any good links pertaining to this topic, please post them too.
If I understand correctly, a business is defined within your system as a "group of users", and your whole system references data belonging to users as opposed to data belonging to a business. You are looking to reference data that belongs to all users who belong to a particular business. In this case, the best and most extensible way to do this would be to create two more tables to contain businesses and business-user relations.
For example, consider you have the following tables:
business => Defines a business entity
id (primary)
name
Entry: id=4, name=CompanyCorp
user => Defines each user in the system
id (primary)
name
Entry: id=1, name=Geoff
Entry: id=2, name=Jane
business_user => Links a user to a particular business
user_id (primary)
business_id (primary)
Entry: user_id=1, business_id=4
Entry: user_id=2, business_id=4
Basically, the business_user table defines relationships. For example, Geoff is related to CompanyCorp, so a row exists in the table that matches their id's together. This is called a relational database model, and is an important concept to understand in the world of database development. You can even allow a user to belong to multiple different companies.
To find all the names of users and their company's name, where their company's id = 4...
SELECT `user`.`name` as `username`, `business`.`name` as `businessname` FROM `business_user` LEFT JOIN `user` ON (`user`.`id` = `business_user`.`user_id`) LEFT JOIN `business` ON (`business`.`id` = `business_user`.`business_id`) WHERE `business_user`.`business_id` = 4;
Results would be:
username businessname
-> Geoff CompanyCorp
-> Jane CompanyCorp
I hope this helps!
===============================================================
Addendum regarding "cases" per your response in the comments.
You could create a new table for cases and then reference both business and user ids on separate columns in there, as the case would belong to both a user and a business, if that's all the functionality that you need.
Suppose though, exploring the idea of relational databases further, that you wanted multiple users to be assigned to a case, but you wanted one user to be elected as the "group leader", you could approach the problem as follows:
Create a table "case" to store the cases
Create a table "user_case" to store case-user relationships, just like in the business_user table.
Define the user_case table as follows:
user_case => Defines a user -> case relationship
user_id (primary)
case_id (primary)
role
Entry: user_id=1, case_id=1, role="leader"
Entry: user_id=2, case_id=1, role="subordinate"
You could even go further and define a table with definitions on what roles users can assume. Then, you might even change the user_case table to use a role_id instead which joins data from yet another role table.
It may sound like an ever-deepening schema of very small tables, but note that we've added an extra column to the user_case relational table. The bigger your application grows, the more your tables will grow laterally with more columns. Trust me, you do eventually stop adding new tables just for the sake of defining relations.
To give a brief example of how flexible this can be, with a role table, you could figure out all the roles that a given user (where user_id = 6) has by using a relatively short query like:
SELECT `role`.`name` FROM `role` RIGHT JOIN `user_case` ON (`user_case`.`role_id` = `role`.`id`) WHERE `user_case`.`user_id` = 6;
If you need more examples, please feel free to keep commenting.
I am developing a social network for an intranet, and I came across a problem [?]. I have the entities User and Business as main entities of the network.
Note: A Business does not have, necessarily, a relationship with a User.
Following this idea, I have a group table, and a group can be created either by a user or by a business, there comes a question, how can I make the author field in this table?
I did the following, I created a table type, with the following data:
id | name
1 user
2 business
And my table groups like this:
id
name
description
tid (FK -> type.id)
author (INT)
Thus, if a group has a tid equals to 1, means that the author is referring to a User, if it have tid equals to 2, it is referring to a Business.
What do you think about this implementation? It is correct?
What can I do to improve it?
I'm using PHP 5.3.6 (Zend Framework and Doctrine2) + MySQL 5.1.
Per request:
The terminology for this is "polymorphic". Bill Karwin had a good answer that I can't find at the moment about it. From a database design perspective, I've been told the logical model term for this is an "arc" relationship. Either way, I see no issues with what you posted, other than supporting multiple authors.
The bad thing about this is that you cannot use the foreign key constraints to check and verify your data if you do this.
I would recommend using 2 tables instead. one to store the relationship between user and group, and one to store the relationship between business and group.
This will allow you to use all the fk benefits like cascading deleted when the group or business or user is deleted.
i want my database to support one company haveing many users how can i do that? exampleusers table(UID,username,password)company table(CID,companyname,usersthatistheownerofthecompany) how can i do that? what should i do ? should i make an array in php like 1241,423,4123 *uid's that will be inserted on usersthatistheownerofthecompany row ? or is there any better idea ?
If you want each user to have one (and never more) company, you should have :
user table
uid
username
...
company_id
company table
company_id
company_name
...
Then, user.company_id would be a foreign key, that references company.company_id.
And, then, you store :
One line in user for each user
Referencing the id of the right company for that user
which is the company_id of the right line in the company table.
And one line for each company in company
There is no user's related information stored in the company table -- and as each user "points" to a company, a company can have several users.
Storing data as an array like you suggested is definitely not quite a good idea -- just not the way a relational database works.
If each user can have several companies, and each comparny can have several users, you'll have to add a third table (a join table), that will indicate, for each user(s), to which company(ies) they are attached to :
user table
uid
username
...
company table
company_id
company_name
...
user_company table
uid
company_id
In this situation, there is no user-related stuff in the company table, and there is no company-related stuff in the user table : the link between those is in the user_company table.
Of course, user_company.uid will be a foreign-key to user.uid ; and user_company.company_id will be a foreign-key to company.company_id.
There is a better idea - it's called a cross-table join. What you do is you create a third table, which contains two columns. In those two columns you store the primary key of the tables you're connecting to eachother.
The idea is that you're creating a relation between a company and a user. In a relational database, relations are indicated between tables by using foreign keys.
Of course, this only applies when you want to connect multiple users to multiple companies (an "M-N" relationship). If you want to connect multiple users to a single company, simply add a column for the company id to the user.
Any relational database is a good way to go. Have a look at MS SQL or MySQL.