Getting confused with SQL foreign key and many to many - sql

Suppose you have students and teachers. A student has only one teacher but teachers have many students.
What is the best way to design it with a relational table ?
Student Teacher
------- -------
pk pk
name name
teacher
or
Student Teacher Relation
------- ------- --------
pk pk pk
name name student
teacher
To me it's more comfortable to use the second solution because web can add fields like
date_joined
or some stuff.
What do you advice ?
Thanks
My choice
Thanks to your advices i've decided to use a dedicated table to be more flexible.

If the relationship, in and of itself, has attributes (that is, they're not attributes of the teacher or the pupil) then yes, that would be a good reason to model it as a separate table.1
On the other hand, if you're only adding these attributes because you now can, then I would favour the first form.
1 You may still want some form of enforcement to ensure that the "A student has only one teacher" constraint is still met, but the details of how to do that precisely may vary between database systems, and on whether the relation table is just modeling current relationships, or also contains historic relationships.

If the student only has one teacher, and you know that for sure, then I would recommend the first alternative.
Even in the first solution you can have fields like date_joined
Student Teacher
------- -------
pk pk
name name
teacher
date_joined
However, quite often a student takes many courses, or has many teachers. If you go with this solution then a student can only have one teacher at the time. So you need to be sure that this is really the case.
If you go with the second solution, and you only want one teacher per student, you can add a unique index for the student. This blocks so one student only can appear once in the relational table.

Related

is it legit to establish a relationship between two subclasses which sharing the same superclass (IS-A relationship)?

I have a question regarding a project I am doing and hope you could provide some help:)
The police were looking for a murder suspect after a person was shot and killed yesterday. The only clue is that the victim has left a note with five people's names on it, and the police needed to find these five people's information by searching on the citizen database (name is not unique so there may be more than five results. To uniquely identify someone you need the citizen ID). After finding the murderer, the police need to make changes to the murderer's criminal record. I am wondering how could I do this?
Since the entity Victim and the entity Murder_suspects both have the same attributes as the entity Citizen, my original plan was to make victim and murder_suspects become two subclasses sharing the same superclass(citizen), that is to say, victim ISA citizen and murder_suspects ISA citizen. However, I am not sure if it is legit to establish a relationship between two subclasses which share the same superclass (IS-A relationship). Also, I think the primary key of murder_suspects should be citizen.name instead of citizen.id, but I don't think that the subclass's primary key could be different from its superclass's primary key. I am wondering if anyone could help with my confusion and give me some suggestions, thanks in advance:)!
P.S. To make it more clear, the entity citizen has the following attributes: id, name, phone_number, address, criminal_record, etc.
Many thanks for any help anyone is able to provide:)
Citizen
-------
Id
FirstName
LastName
DateOfBirth
Sex
Address
------
Id
Street
House
City
Case
----
Id
Name
Date
Victim
-------
Id
CitizenId
CaseId
SomeUniqueToVictimProperty
Suspect
-------
Id
CitizenId
CaseId
SomeUniqueToSuspectProperty
Also, I think the primary key of murder_suspects should be citizen.name instead of citizen.id
I would stick to CitizenId not CitizenName. Its faster to look by int/bigint than by varchar/text. Also I would add Id as a PK in both victim and suspect because after some time with more and more cases you would have a problem: everyone can commit only one crime because citizen record is already in "suspect" table under another case? You might make two column PK (CitizenName + CaseId), but why?
I wouldn't connect victim to a suspect. You may connect victim to a crime and suspect to a crime. There is nothing that links them directly. Case is linking them so stick to reality.
the entity citizen has the following attributes: id, name, phone_number, address, criminal_record, etc.
Maybe that too much but how about putting address to another table?
what if someone has two addresses? of two different kinds?
Phone number might be in address or in "Contact" table?
Criminal_record? with what? enormous text of all crimes? I would
stick to relations to "suspect" table or something like that

How do you add a field that gives the chronological number value of each lesson for a specific student?

I am making a prototype for a database in Access. I have a student table, and a lesson table. one student can have many lessons. I want a field that says which lesson that was for the student, e.g. 'lesson 3'. I am very open to advice on making new tables, queries, fields, etc, my database is a prototype, so if you think it would be better to completely change it, then I am open to suggestions.
This may not be what you are looking for but I would change the relationship ship to a many to many relationship facilitated by a join table between student and lessons. The join table would have a composite primary key made of the two foreign keys referencing the student and lessons primary keys. I would do this because at any time a student can have many lessons but a lesson can also have many students present at any time.
Then in the lesson table you may want to add the chronological number of the lesson as a column named ChronoNumber or something to that effect. The ChronoNumber may repeat a bit but at least you will be able to use the one table to facilitate all the students and all the lessons.

How would this relationship be represented?

I'm trying to figure out how to structure this relationship between student, teacher and classroom.
Each teacher has 1 or more students.
Now considering that,
Students have one or more teachers, but all said teachers must teach from the same classroom.
After tinkering around I have gotten to this stage (http://i.imgur.com/XfLFPtb.png) , but it feels wrong. Or perhaps instead of linking teacher to room, maybe student to room? I'm not sure.
I'm not sure whether it would also cover the case when for example, you might have 3 teachers (can be more, just an example). Where "teacher_1" and "teacher_2" teach "student_1", "teacher_2" and "teacher_3" teach "student_2". Even though they teach from the same room, "teacher_1" and "teacher_3" aren't sharing students.
EDIT:
Each student is taught from the one classroom. i.e students can only be taught from one room.
I could have stated that, but that's what I thought was implied.
You are actually mostly right in your diagram. Basically teachers and students are definitely different tables as you have teacher and student, and they would be linked by a link table called teacher_student with dual primary keys off those tables. In other words, you have what is considered a many-to-many relationship, and using a link table is correct.
One change: you have the primary keys set up as VARCHAR. That is a bit odd. I would use INT for a primary key for both the teacher and student tables, and these would typically be set up as autoincrement.
It's not entirely clear that you need a separate table for classroom if all teachers teach from the same classroom, however if you mean that each teacher teaches all of his or her individual classes from that classroom, then there's another question. If there is a one-to-one relationship between teacher and classroom, you only need to have classroom set up as an extra key on teacher and no need for another table. In other words, your classroom table becomes unnecessary. If teachers share a few classrooms, then you could have a separate table listing the classrooms, and then on teacher you would have a foreign key for classroom_id which would then link to the controlled table of classroom.
Edit:
One last clarification. Teacher and Student tables are essentially correct. just change the variable to INT. teacher_id is the primary key on teacher; student_id is the primary key on student, and both serve both as foreign keys and dual primary keys on teacher_student.
As a suggestion, you may want to consider an entity representing a class or course. One class can have many students. A teacher can teach many classes. A room has many classes. This might help resolve your relationships. (A classroom can only have one class at a time.)
Hope my logic makes sense.

Joining 2 primary key columns to 1 foreign key column in the same table

I have a jobs table with a projectmanagerid and a projectdirectorid e.g
jobs
----------------
pk jobid
pk projectmanagerid
pk projectdirectorid
Both these id columns need to link to an employees table using the employeeid pk as the link. Is this good practice or is there a better way?
employees
------------------
pk employeeid
other stuff
This seems OK as long as you're only going to have those two types: Manager and Director. But think about whether you might need to add another employee type, for example Coordinator, in the future. If that's a possibility then you've got a many-to-many relationship between jobs and employees that you should resolve by using an intermediary junction table, perhaps also adding a third table to describe the employee's role on the job (Manager, Director, ...).
Nothing wrong with it and it's perfectly acceptable. The field names are descriptive and thereby signify that you do actually need to have two different FKs pointing at the users table. if it was x and y, then it'd look weird.
Seems quite reasonable -- and common in many heirarchies -- to have two relationships to the same table. As with all foreign keys, but perhaps even more so in this case, use cascading carefully. I'm guessing that deletion of the manager or director should not result in deletion of the job record.
There is a rule of thumb that states a table models an entity/class or the relationship between entities/classes but not both. Therefore, consider creating two relationship tables to model the two relationships, project managers and project directors respectively. I don't recommend Joe Stefanelli's employee_role_id approach. I think you will find that the attributes for each role (yes, relationships do indeed have attributes too) will be too different to make the generic table approach to add value.

Database design....storing relationship in one table, and the data in another table?

I'm looking at this company's database design, and would like to know the purpose of their design, ie store relationship in one table and the data in another, why do this?
They have this,
EMPLOYEE
Id (PK)
DepartmentId
EMPLOYEE_DATA
EmployeeId (PK)
First Name
Last Name
Position
etc...
Rather than this...
EMPLOYEE
Id (PK)
DepartmentId
First Name
Last Name
Position
etc...
...OR this...(employee can belong to many departments)
EMPLOYEE
Id (PK)
First Name
Last Name
etc...
EMPLOYEE_DEPARTMENT
Id
EmployeeId
DepartmentId
Position
That's a link table, or join table, or cross table.. lots of different names.
How would you assign an employee to two different departments with your design? You can't. You can only assign them to one.
With their design, they can assign the same ID to multiple departments by creating multiple records with the employee ID and different department ID's.
EDIT:
You need to be more specific about what you're asking. Your first question seemed to be asking what the purpose of mapping table was. Then you changed it, then you changed it again.. none of which makes much sense.
It seems now that you are asking what the better design is, which is a totally different question than what you originally asked. Please state specifically what question you want answered so we don't have to guess.
EDIT2:
Upon re-reading, if this is the actual design, then no.. It does not support multiple department id's. Such a design makes little sense, except for one situation. If the original design did not include a department, this would allow them to add a department ID without modifying the original EMPLOYEE_DATA table.
They may not have wanted to update legacy code to support the Employee id, so they added it this way.
Purpose of design is determined by business rules.
Business rules dictate entity (logical model perspective) / table (physical model perspective) design. No design is "bad" if it is built according to the requirements that were determined based on business rules. Those rules can however change over time -- foreseeing such changes and building to accommodate/future-proof the data model can really save time, effort and ultimately money.
The first and third example are the same -- the third example has an extraneous column (EMPLOYEE_DEPARTMENT.id). ORMs don't like composite keys, so a single column is used in place of.
The second example is fine if:
employees will never work for more than one department
there's no need for historical department tracking
Conclusion:
The first/third example is more realistic for the majority of real-world situations, and can be easily customized to provide more value without major impact (re-writing entire table structure). It uses what is most commonly referred to as a many-to-many relationship to allow many employees to relate to many departments.
If an employee can be in more than one department, then you would need a mapping table but I'd do it like the following:
EMPLOYEE
Id (PK)
First Name
Last Name
DEPARTMENT
Id (PK)
Name
EMPLOYEE_DEPARTMENT
EmployeeId_fk (PK)
DepartmentId_fk (PK)
Position
This would allow for multiple positions in multiple departments.
You would do this if an employee can be a member of multiple departments. With the latter table, each employee can only belong to one department.
The only remotely good reason for doing this is to implement an extension model where the master table identifying unique customers does not include all the data for customers that is not always necessary. Instead, you create one core table with the core employee data and and extension table with all the supplementary fields. I've seen people take this approach to avoid creating large tables with many columns that are rarely needed. However, in my experience it's typically premature optimization, and I wouldn't recommend it.
In contrast to many responses, the model included does not support multiple departments per employee - it is not a many to many mapping approach.