How would this relationship be represented? - sql

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.

Related

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 to ensure referential integrity many not strictly hierarchical entities?

Say I have three entities(or tables): School, Student and Classroom. How do I ensure a Student belongs to a Classroom which belongs to the same School the Student belongs to? Considering a Student may not be part of any Classroom.
I'm facing that problem in many other ways. For example, when I add the entity Teacher. How can I guarantee at database level that a Teacher teaches on a Classroom of the same School the Teacher belongs to? And so on...

Getting confused with SQL foreign key and many to many

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.

Setup Many-to-Many tables that share a common type

I'm preparing a legacy Microsoft SQL Server database so that I can interface with in through an ORM such as Entity Framework, and my question revolves around handling the setup of some of my many-to-many associations that share a common type. Specifically, should a common type be shared among master types or should each master type have its own linked table?
For example, here is a simple example I concocted that shows how the tables of interest are currently setup:
Notice that of there are two types, Teachers and Students, and both can contain zero, one, or many PhoneNumbers. The two tables, Teachers and Students, actually share an association table (PeoplePhoneNumbers). The field FKID is either a TeacherId or a StudentId.
The way I think it ought to be setup is like this:
This way, both the Teachers table and the Students table get its own PhoneNumbers table.
My gut tells me the second way is the proper way. Is this true? What about even if the PhoneNumbers tables contains several fields? My object oriented programmer brain is telling me that it would be wrong to have several identical tables, each containing a dozen or so fields if the only difference between these tables is which master table they are linked to? For example:
Here we have two tables that contain the same information, yet the only difference is that one table is addresses for Teachers and the other is for Students. These feels redundant to me and that they should really be one table -- but then I lose the ability for the database to constrain them (right?) and also make it messier for myself when I try to apply an ORM to this.
Should this type of common type be merged or should it stay separated for each master type?
Update
The answers below have directed me to the following solution, which is based on subclassing tables in the database. One of my original problems was that I had a common table shared among multiple other tables because that entity type was common to both the other tables. The proper way to handle that is to subclass the shared tables and essentially descend them from a common parent AND link the common data type to this new parent. Here's an example (keep in mind my actual database has nothing to do with Teachers and Students, so this example is highly manufactured but the concepts are valid):
Since Teachers and Students both required PhoneNumbers, the solution is to create a superclass, Party, and FK PhoneNumbers to the Party table. Also note that you can still FK tables that only have to do with Teachers or only have to do with Students. In this example I also subclassed Students and PartTimeStudents one more level down and descended them from Learners.
Where this solution is very satisfactory is when I implement it in an ORM, such as Entity Framework.
The queries are easy. I can query all Teachers AND Students with a particular phone number:
var partiesWithPhoneNumber = from p in dbContext.Parties
where p.PhoneNumbers.Where(x => x.PhoneNumber1.Contains(phoneNumber)).Any()
select p;
And it's just as easy to do a similar query but only for PhoneNumbers belonging to only Teachers:
var teachersWithPhoneNumber = from t in dbContext.Teachers
where t.Party.PhoneNumbers.Where(x => x.PhoneNumber1.Contains(phoneNumber)).Any()
select t;
Teacher and Student are both subclasses of a more general concept (a Person). If you create a Person table that contains the general data that is shared for all people in your database and then create Student and Teacher tables that link to Person and contain any additional details you will find that you have an appropriate point to link in any other tables.
If there is data that is common for all people (such as zero to many phone numbers) then you can link to the Person table. When you have data that is only appropriate for a Student you link it to the Student ID. You gain the additional advantage that Student Instructors are simply a Person with both a Student and Teacher record.
Some ORMs support the concept of subclass tables directly. LLBLGen does so in the way I describe so you can make your data access code work with higher level concepts (Teacher and Student) and the Person table will be managed on your behalf in the low level data access code.
Edit
Some commentary on the current diagram (which may not be relevant in the source domain this was translated from, so a pinch of salt is advised).
Party, Teachers and Learners looks good. Salaries looks good if you add start and end dates for the rate so you can track salary history. Also keep in mind it may make sense to use PartyID (instead of TeacherID) if you end up with multiple entites that have a Salary.
PartyPhoneNumbers looks like you might be able to hang the phone number off of that directly. This would depend on if you expect to change the phone number for multiple people (n:m) at once or if a phone number is owned by each Party independently. (I would expect the latter because you might have a student who is a (real world) child of a teacher and thus they share a phone number. I wouldn't want an update to the student's phone number to impact the teacher, so the join table seems odd here.)
Learners to PaymentHistories seems right, but the Students vs PartTimeStudents difference seems artificial. (It seems like PartTimeStudents is more AttendenceDays which in turn would be a result of a LearnerClasses join).
I think you should look into the supertype/subtype pattern. Add a Party or Person table that has one row for every teacher or student. Then, use the PartyID in the Teacher and Student tables as both the PK and FK back to Party (but name them TeacherID and StudentID). This establishes a "one-to-zero-or-one" relationship between the supertype table and each of the subtype tables.
Note that if you have identity columns in the subtype tables they will need to be removed. When creating those entities going forward you will first have to insert to the supertype and then use that row's ID in either subtype.
To maintain consistency you will also have to renumber one of your subtype tables so its IDs do not conflict with the other's. You can use SET IDENTITY_INSERT ON to create the missing supertype rows after that.
The beauty of all this is that when you have a table that must allow only one type such as Student you can FK to that table, but when you need an FK that can be either--as with your Address table--you FK to the Party table instead.
A final point is to move all the common columns into the supertype table and put only columns in the subtypes that must be different between them.
Your single Phone table now is easily linked to PartyID as well.
For a much more detailed explanation, please see this answer to a similar question.
The problem that you have is an example of a "one-of" relationship. A person is a teacher or a student (or possibly both).
I think the existing structure captures this information best.
The person has a phone number. Then, some people are teachers and some are students. The additional information about each entity is stored in either the teacher or student table. Common information, such as name, is in the phone table.
Splitting the phone numbers into two separate tables is rather confusing. After all, a phone number does not know whether it is for a student or a teacher. In addition, you don't have space for other phone numbers, such as for administrative staff. You also have a challenge for students who may sometimes teach or help teach a class.
Reading your question, it looks like you are asking for a common database schema to your situation. I've seen several in the past, some easier to work with than others.
One option is having a Student_Address table and a Teacher_Address table that both use the same Address table. This way if you have entity specific fields to store, you have that capability. But this can be slightly (although not significantly) harder to query against.
Another option is how you suggested above -- I would probably just add a primary key on the table. However you'd want to add a PersonTypeId field to that table (PersonTypeId which links to a PersonType table). This way you'd know which entity was with each record.
I would not suggest having two PhoneNumber tables. I think you'll find it much easier to maintain with all in the same table. I prefer keeping same entities together, meaning Students are a single entity, Teachers are a single entity, and PhoneNumbers are the same thing.
Good luck.

OOP: Class A and Class B is depend together. Is this well design?

I have read some UML class diagram. I see some UML design this way:
For example: there are two class: class Student and class Transcript. Every student has a transcript, and every transcript is together with a student. So, class Student and class Transcript is depend together. So, is this a well design class ?
If not, how can we fix this. And if this is OK, how can I implemented this relation well ?
Thanks :)
I wouldn't say it's a very good design: apparently, you want student.transcript.student == student and transcript.student.transcript == transcript to be true at any given moment, right? But what about Students without Transcripts? Transcripts without Students? If those are prohibited, you may end in a funny situation: you'll have to create corresponding Student and Transcript at the same time!
Well, in database area, this is usually modeled with three tables (which may or may not correspond directly to actual physical tables):
TABLE Student ( studentId ID PRIMARY KEY, ... )
TABLE Transcript ( transcriptId ID PRIMARY KEY, ... )
TABLE StudentTranscriptLink (
studentId ID NOT NULL UNIQUE REFERENCES Student(studentId),
transcriptID Id NOT NULL UNIQUE REFERENCES Transcript(transcriptId)
) PRIMARY KEY ( studentId, transcriptId )
The UNIQUE constraints ensure that if you take Student, get its Transcript, and get that Transcript's Student, you return to the original Student you started with; the same is true with Transcript->Student->Transcript navigation.
In the OOP world you probably would have some sort of StudentTranscriptDispatcher with List<Pair<Student, Transcript>> inside, and methods for turning Student into Transcript and back.
However, such bi-directional relationships are... unusual. It's basically having one large object sliced in two halves -- but still keeping those halves tied together very tightly. Why would you do this? It doesn't remove any complexity, on the contrary: it introduces new, artificial complexity which wasn't there before.
What you should probably think about here is navigability. It sounds like the relationship is entirely appropriate, however, do you ever have to navigate from Transcript to Student? If not, your relationship is not bi-directional and Transcript is no longer dependent on Student. Do you always locate a Student first and then a Transcript?
To be honest, I wouldn't worry about it too much. If it works for you - go with it!