Role table
RoleID Desc
1 primary
2 secondary
3 alternate
Users
UserID Name
1 ann
2 saylor
3 jim
4 ken
5 kathy
Route table
RouteID Name
1 x
2 y
RouteRoleUser table
RouteID RoleID UserID
1 primary ann
1 secondary saylor
1 alternate jim
1 alternate ken
1 alternate kathy
I have a grid which shows the following:
Route | Primary Pumper | Secondary Pumper | Alternate Pumpers (comma separated)
x ann saylor jim, ken, kathy
My requirements are:
Any route can have only one primary user
Any route can have 0 or one secondary user
Any route can have 0 or more alternate users
All users of a route are unique
How can I have the requirements restriction from a db design perspective in the RouteRoleUser table? Currently if I make Route, Role and User as candidate key, it does not
stop anyone to add two primary users for a route.
Is there a better way?
For the "Any route can have N number of (type) user(s)" rule, you could validate this by using an INSTEAD OF INSERT trigger and preventing the insert. I personally handle this type of logic at the application or stored procedure level.
For the "All users of a route are unique" you can enforce this with a UNIQUE constraint on RouteID, UserID.
Related
I have two tables:
People:
Id | OrgId | Name
-----------------
1 10 Sam
2 10 Dana
3 12 Max
Id is a primary key. OrgId is foreign key to other table.
And second table Cars:
Id | Name | OrgId | PersonId
----------------------------
1 Volvo 10 1
2 BMW 10 2
Here: Id is a primary key. PersonId is a foreign key to People table. OrgId is foreign key to Organization table.
So I have Person which are attached to Organization and I have Cars which are attached to Organization and Person.
I need to guarantee that it will be impossible to attach Car from one Organization to Person from another Organization. The record:
Id | Name | OrgId | PersonId
----------------------------
1 Volvo 12 1
must be impossible because Car belongs to Organization with ID = 12, but Person belongs to Organization with ID = 10.
What is the best way to do it ?
I see two ways:
Foreign key using two fields People (Id + OrgId) <-> Cars (PersonId + OrgId).
But in this case I need to create one additional unique index on the table People ('Id+OrgId`).
Trigger on the table Cars.
What do you recommend to use in this case ?
My first reaction is to look up the organization using the person column. But, that doesn't really fit the situation -- cars are owned by organizations independently of people. So, you might need the organization, even if no person is assigned.
So, add a new key to people:
alter table people add constraint unq_people_orgid_id unique (orgid, id);
Then use this for the foreign key reference in cars:
alter table cars add constraint
foreign key (orgid, personid) references people(orgid, id);
Note that the second key is redundant. But it allows a reference that includes the organization.
I wouldn't use OrgId in your cars table, it violates normalization rules. You can use a query to get the organization information for the car using the PersonId.
I am building an database schema for a project and I am bit stuck on this issue. I have 2 tables:
USER table:
Id Name Contact_ID
1 Arun 2
2 Barath 3
3 Charan 2
4 Dinesh 1
CONTACT table:
ID Name Phone Mail
1 Mahesh 1234 Mahesh#Yahoo.com
2 Suresh 54321 Sureh#Google.com
3 Jayesh 9876 Jayesh#Bing.com
4 Ganesh 98754 Gahesh#Safari.com
Each of the users in USER will have a contact in CONTACT.
If a user has a single contact then I can use a foreign key relationship on Contact_ID in USER and build the relationship between them.
But what if an user in the USER table has multiple contacts in the CONTACT table? I am not sure how to build the relationship between them.
Eg:
In USER for user Charan there is one contact, contact 2, but what if there is one more, contact 4?
In that case how can I build the many to one relationship?
It looks like you've got it backwards. Your CONTACT table should have a foreign key reference to USER table, rather than USER containing a foreign key reference to CONTACT. For example:
USER table
Id Name
1 Arun
2 Barath
3 Charan
4 Dinesh
CONTACT table
ID Name Phone Mail USER_ID
1 Mahesh 1234 Mahesh#Yahoo.com 1
2 Suresh 54321 Sureh#Google.com 2
3 Jayesh 9876 Jayesh#Bing.com 1
4 Ganesh 98754 Gahesh#Safari.com 3
Of course, I just used fake data for the new USER_ID column. As you can see, USER with Id 1 (Arun) has multiple contacts (IDs 1 and 3) in the CONTACT table.
In the relational model (and ER model) tables represent (business/application) relationships/associations. FKs (foreign keys) are called "relationships" by pseudo-relational (& pseudo-ER) methods.
-- user "id" has name "name" and ...
user(id, name, ...)
-- contact "id" has name "name" and ...
contact(id, name, ...)
-- user "uid" has contact "cid"
user_has_contact(uid, cid)
If user_has_contact is N:1 in uid:cid then you can replace user & user_has_contact by:
-- user "id" has ... AND user "id" has contact "cid"
user(id, name, ..., cid)
If user_has_contact is 1:N in uid:cid then you can replace contact & user_has_contact by:
-- contact "id" has ... AND user "uid" has contact "id"
contact(id, name, ..., uid)
You should use the first design for M:M. (You don't actually have to but then the joined tables exhibit problems that normalization would tell you to solve by having the separate tables.) This is called an association/junction/join/many-to-many/bridge table in methods that call FKs "relationships". But like every table it represents a relationship/association on some values. (And hence also any identified entities.) It also handles M:0-or-1 & 0-or-1:M . The other two designs can do that too using NULL.
Regardless of the cardinality of user_has_contact it is probably a good idea to keep the three separate because it is straightforward. (True ER modeling would give the two entity tables & one association table.) But you should realize that there is no need to join them.
A FK tells the DBMS that values for a list of columns in a table must appear as a CK (candidate key) elsewhere. (In SQL, a FK says they appear as a superkey, ie SQL PK (primary key) or UNIQUE NOT NULL, elsewhere.)
(Methods that call FKs "relationships" do so because FKs are associated with relationships like user_has_contact that have be joined into what becomes the referencing table. Also it is those relationships' cardinalities that are called the FKs' cardinalities. But a FK constraint just states a fact; it isn't a relationship/association.)
You need to find & follow references for information modeling & database design.
I am trying to make a constraint that will keep ids unique for specific users.
Each user is a separate entity within the world so 2 people having 1 as id is not a problem. I just don't want one person to have the same id twice.
For example:
This would be acceptable:
User Id
John 1
John 2
Alice 1
Alice 2
This would not be ok:
User Id
John 1
John 1 -- problem
Alice 1
Alice 2
Just add a Unique constraint over both columns to your CREATE TABLE statement:
CREATE TABLE person(
... -- more columns
username text
,person_id int
,UNIQUE (username, person_id)
);
That does it. I see that #Hamlet and #Frank already commented likewise.
Creating a unique index on these two columns would also work. This is usually what happens under the covers to enforce the constraint.
In Laravel 4's Eloquent,
i have a table user and a field user.friend_id which is an also an id of a user..
but when i try to create a new user with friend_id = 0, the foreign key fails..
and when friend_id = 1, it succeeds.
I have this in my user's schema builder
$table->unsignedInteger('friend_id')->default(0)->nullable();
what should I be doing here?
should i have just created a pivot table instead?
thanks!
You should not set default value 0 for a null able foreign key.
Correct way:
$table->unsignedInteger('friend_id')->nullable();
Explanation:
$table->unsignedInteger('friend_id')->default(0)->nullable();
When you try to insert a new record, and leave the friend_id blank.
The database takes the default value for the field ie: 0
since it's a foreign key, to maintain relational integrity, it will look for a record having primary key 0. (which naturally does not exist)
Assuming you can have more than one friend, then yes, you should have a pivot table
User table
id | name
1 | Laurence
2 | Ben
3 | Jane
Users_Friend table
user_id | friend_id
1 | 2
1 | 3
This means Laurence is friends with Ben and Jane
I develop simple DB and I have confused with next issue: I have separated entities(tables) for 'Employe', 'Author' and 'Manager'. In table 'Employe' I have column 'Appointment' that can containe some vocation in particular 'Author' and 'Manager' (but it also can containe another vocation for example 'Seller', 'CopyRighter' etc). How can I implement it in my DB? What relationships have I use?
I think you should consider abstracting your vocations into a Role table. Cosider the following structure:
RoleID | RoleName
1 | Author
2 | Manager
3 | Copyrighter
etc...
Then your Appointment column of the Employee table will contain a foreign key (RoleID) to this Role table: