SQL : ER Model, Foreign keys - sql

I have a simple question, but I am still confused about it.
Whenever you design an ER model, how are you supposed to draw PK's and FK's ?
Let's say I have two tables, User and Country
User
ID | firstName | lastName | FKCountry
1 | John | Stewart | 1
2 | Paul | Duschmol | 2
etc.
Country
ID | country | code
1 | Germany | GER
2 | Switzerland | CH
etc...
Well, should I add the column "FKCountry" in the ER model or not ? I mean, there will be the relation (Rhombus) between both entities, but should I explicitly add the "FKCountry" by the User entity ?
Hope my question is clear, Thank you in advance :)

The primary purpose of Foreign Key is to enforce referential integrity between the two tables.
If the relationship of Country to a User is One-to-Many then it should be fine for adding column FKCountry on table User.
However, if the relationship is Many-to-Many in which Country can have many User as well as User belongs to multiple Country, then a 3-table design is much preferred. Wherein the 3rd table is the association table between the other two.

Yes, you should add FKCountry to the User table in your ER diagram. If the column exists in your table, it should be represented in the entity. There should be zero doubt that the relational marker connects Country.ID to User.FKCountry. Just because it is obvious in this example does not mean that in other relationships, the linked columns might not be named completely differently and not obvious.

Related

SQL One-to-Many relation

I am designing a database for an application and i have encountered a problem.
The database is supposed to track patients and their pills.
I figured that I needed a relational database and that is what I am trying to implement and this is my problem:
I need a patient to be associated with multiple pills, not just one.
All I've found online was a table where pills were associated with the person and not the other way around.
Thanks for helping
This is not a One-to-Many, but a Many-to-Many relation: a patient could have more pills, but the same kind of pill could be taken by a lot of patient.
SO you should have 3 tables:
The Patient table
id | name | surname
The pills table
id | name | pharmaceutic_company
The realtion table
id_patient | id_pill | date

PHP Junction Table Relations (Many to Many), grasping concept

So I've tried searching and have yet to find out how to grasp this entirely.
I'm reorganising my database because I was storing user id's as comma separated values in a column withing that row to control permissions. To me, this seems like a better and faster(hardware) way, but I'm moving towards this "proper" way now.
I understand that you need 3 tables. This is what I have.
Table 1. members -> ID | user_name
Table 2. teams -> ID | team_name
Table 3. team_members -> ID | team_fk | member_fk
I understand how to store data in another column and use sql data to display it. What I'm confused about is why I have to link(relation) the columns to the ID's of the other tables. I could get the data without using the relation. I'm confused by what it even does.
Furthermore, I would like to have multiple values that determine permissions for each team. Would I do:
Table 3. team_members -> ID | team_fk | member_fk | leader_fk | captain_fk
^setting 0 or 1(true or false) for the leader and captain.
Or would I create a table(like team_leaders, team_captains) for each permission?
Thanks for the help!
Ryan
It seems that "leader", "captain and "regular member" are roles in your team. So you can create table team_roles, or just assign roles as strings to your relation table, i.e.
team_members -> ID | team_fk | member_fk | role
The key thing about this is to keep your database [normalised]https://en.wikipedia.org/wiki/Database_normalization. It is really easier to work with normalised database in most cases.
What I'm confused about is why I have to link(relation) the columns to the ID's of the other tables. I could get the data without using the relation.
You don't have to declare columns as foreign keys. It's just a good idea. It serves the following purposes:
It tells readers of the schema how the tables are related to each other. If you name the columns well, this is redundant -- team_fk is pretty obviously a reference to the teams table.
It enables automatic integrity checks by the database. If you try to create a team_members row that contains a team_fk or member_fk that isn't in the corresponding table, it will report an error. Note that in MySQL, this checking is only done by the InnoDB engine, not MyISAM.
Indexes are automatically created for the foreign key columns, which helps to optimize queries between the tables.
Table 3. team_members -> ID | team_fk | member_fk | leader_fk | captain_fk
If leader and captain are just true/false values, they aren't foreign keys. A foreign key column contains a reference to a key in another table. So I would call these is_leader and is_captain.
But you should only put these values in the team_members table if a team can have multiple captains and leaders. If there's just one of each, they should be in the teams table:
teams -> ID | team_name | leader_fk | captain_fk
where leader_fk and captain_fk are IDs from the members table. This will ensure that you can't inadvertently assign is_captain = 1 to multiple members from the same team.

What should a relationships table look like - Need confirmation of my technique

Lets say I have 3 models:
User
Page
Comments
I asked a question based on if I should have each model keep track of its relationships: SQL relationships and best practices
an example of this would be a "Pages" table that states who its author was... The problem seemed to be that if 2 users were the author of the one page, you'd have to add a new specific table called PageRelationshipsWithUsers that might have a reference to the PageID and the UserID that created it and a separate row for the co-author.
Understandably this sounds a bit naff. I would end up with a heck load of relation tables and most likely, it could be replaced with just the one multi-purpose relationship table... So I decided to come up with a relationships table like the following:
Relationships Table New
RelationshipID | ItemID | LinkID | ItemType | LinkType | Status
-----------------------------------------------------------------------------
1 | 23(PageID) | 7(UserID) | ("Page") | ("User") | TRUE
2 | 22(CommentID) | 7(UserID) | ("Comment") | ("User") | TRUE
3 | 22(CommentID) | 23(PageID) | ("Comment") | ("Page") | TRUE
however, I would very much appreciate some input as to how good of an idea laying out my relationships table like this is.
Any thoughts?
Answer was told to me by a work colleague:
Imagine the above relationships table for the model "Book"
A User can Rent a book, so the relation is User -> Book...
But what if he can buy a book too: User->Book....
Ooops, we need a new relationship... and considering this relationship table was supposed to be the 1 size fits all, we now have a requirement to add a new separate table... whoops.
So the answer is NO NO NO. don't, it's naughty. Keep your relationship tables separate and specific.
Your suggestion for a relationship table is not optimal for several reasons:
It's difficult to write queries that join tables through the relationship table, as you will need filters on the ItemType and LinkType columns, which is not intuitive when writing queries.
If a need arises to add new entities in the future, that use different datatypes for their primary keys, you cannot easily store ID's of various datatypes in your ItemID and LinkID columns.
You cannot create explicit foreign keys in your database, to enforce referential integrity, which is possibly the best reason to avoid the design you suggest.
Query performance might suffer.
When normalizing a database, you should not be afraid to have many tables. Just make sure to use a naming convention that makes sense and is self-documenting. For example, you could name the relation table between authors and pages "PageAuthors", instead of "Pages".

is this database designed correctly?

I appeared for an interview which went quite well according to me but not according to the interviewer. He asked me several questions which I answered correctly and 2 practicle questions. One of them was related to database.
The question was something like this
A school consist of several classes and each class studies different subjects which are taught by several teachers. You have to design the database so that one can know that which teacher teaches what subject to what class?
It appeared quite simple and I designed it.
something like:
Teacher table
| ID | Teacher_Name |
-----------------------------
| 1 | Ankit |
| 2 | Jack |
Class table
| ID | class_Name |
-----------------------------
| 1 | First |
| 2 | Second |
Subject table
| ID | subject_Name |
-----------------------------
| 1 | English |
| 2 | stats |
and a master table to combine them all and to know what teacher teaches what subject to which class
Master table
| ID | Teacher_id | class_id | subject_id |
----------------------------------------------------
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
Just to clear out what I made...I even wrote a select query for the problem even though he didn't asked me to do so.
I am just a beginner at sql so I don't know is this the right way or not but according to me it is quite useful in case I need to make changes to the database. Example addition of a class or a subject.
Now according to him this design will not work at all and He said that I should not even consider my self as a beginner but below the level of beginner.
So please be kind enough to tell me that is this right or not and if its not what is the right way to design the database.
thanks in advance.
It appeared quite simple
That's probably part of the problem. Most database problems appear quite simple. But few of them actually are quite simple.
Not every teacher is qualified to teach every subject in every school. You probably
need a table that pairs teachers with the subjects they're qualified
to teach.
Some entities carry their full identification in their name.
(Subjects seem to; people don't.) Failing to provide a unique
constraint on, say, "subject_name" would be a mistake, regardless of
whether that table has an id number (which might easily be another
mistake).
"Master" isn't a term in the problem domain. That is, if you look at
a college course catalog, you won't find a chapter or section
entitled "Master chapter", or anything remotely like that. But you
will find a section that tells you which subject is offered during each semester, and
that's a clue. In a college, not every course is
available during every semester.
You also need a unique constraint on the "master" table {teacher_id,
class_id, subject_id}.
In that same table, you need overlapping foreign key constraints on
{teacher_id, subject_id} and {class_id, subject_id}.
I could go on. But here's why I wouldn't have hired you.
You were given ambiguous, incomplete requirements. (That's probably not an accident.) You didn't do enough to clarify them.
I am just a beginner at sql
We were all beginners at some point.
Did they want to hire a beginner? If not, that might be another problem.
Except for one glitch it seems fine, the glitch it in the Master Table if you assign a teacher to a class with wrong subject, you cannot put a constraint for that in database, IMHO there shoul be one more intermediary table which maps classes and subjects i-e ClassSubjectMap
----------------------------------------------------
| CSMapID | class_id | subject_id |
----------------------------------------------------
| 1 | 1 | 1 |
----------------------------------------------------
| 2 | 2 | 2 |
----------------------------------------------------
Then this map ID is used in Master table to map teachers with subject, this way a teacher cannot be assigned to teach biology to an engineering class. Except for this other tables seem fine.
About multi-valued-dependency and 4NF
Maybe you don't want to explicitly store information about what subjects can be taught by a particular teacher. Actually, we have a real application on educational process, where we don't store such information, and we haven't needed it badly enough to implement yet. So i guess you can go without it too, given that you weren't provided with requirements to restrict users on assigning teacher to subjects and classes.
What i think you would want to restrict is to have just one teacher for each subject taught to a particular class. So i would go for something simple, like table named "Courses", with columns {id, teacher_id, subject_id, class_id, semester_num}, and a unique constraint on {subject_id, class_id, semester_num}, keeping teacher as an attribute here.

Storing a hierarchy tree in SQL where each son can have several fathers

I'm trying to store a hierarchical tree in SQL. In my case, the same son can have many fathers (the tree represents a VLSI design where the same cells can be used several times in different designs).
All models I've found on the web describe the employee/manager relationship where each employee has one manager. In my case, the number of fathers can be quite large and if I try to store all of them in a table field, they can exceed the character limit of the field.
Can anyone suggest a better method for storing this tree ?
Thanks,
Meir
One possible way to store this relationship in a relational database would be to create two tables - EMPLOYEE_TABLE and EMPLOYEE_MANAGERS_TABLE
create table EMPLOYEE_TABLE(
emp_id number,
emp_name varchar(200),
primary key(emp_id)
)
create table EMPLOYEE_MANAGERS_TABLE (
id number,
emp_id number,
manager_id number,
primary key(id),
foreign key(emp_id) references employee_table(emp_id),
foreign key(manager_id) references employee_table(emp_id)
)
EMPLOYEE_MANAGERS_TABLE will contain one row per employee_manager relationship.
You can apply the same schema to store the father-son relationship where a son can have more than 1 father.
Use a link table. I'm going to assume you are talking about people and will use that vernacular.
You have a person_table listing all the people and their respective id's. You then have a father_son_table describing the links between each person. Eg.
person_table
id | Name
1 | Matthew
2 | Mark
3 | Luke
4 | John
Say Matthew is Mark's father and Mark was father to Luke and John. In the father_son_table you would have:
father_son_table
id | father_id | son_id
1 | 1 | 2
2 | 2 | 3
3 | 2 | 4
Here you can define as many fathers and sons as you wish.
the number of fathers can be quite large and if I try to store all of them in a table field
eh? Your data is not normalised if you're trying to put multiple values in the same field.
While you say its hierarchical this usually implies that a node has a single 'parent' and 0 or more descendants. If that's not the case then its NOT a hierarchical data model - its a M:N relationship.
Or do you mean that there each node exists in more than one hierarchy?
The question is imposible to answer unless you provide an accurate description of the relationship between records.
You find some clever methods for tree handling in the book of Joe Celko:
http://www.amazon.com/Joe-Celkos-SQL-Smarties-Programming/dp/1558605762
...however, I don't know if it covers your problem
You might want to consider what queries you will most frequently be running against this table. Different strategies for storing hierarchies have advantages / disadvantages based on how the hierarchy is used.
Also, any single-parent strategy for storing a hierarchy could be adapted to handle multiple parents simply by treating each element of the tree as a pointer. Pointers under different parents could each point to the same record.
I would go for additional many-to-many connection table with father_id and son_id columns.