Modelling: Relationship of three Tables - mysql

I have three entities: students, professors and essay_topics.
Situation: students can write several essays with an essay_topic under supervision of a professor. (bold: entities)
But they can only write an essay under supervision of a specific professor once. (not two times the same professor)
And they can not write an essay with the same essay_topic as they did.
That's the only restriction, but it should be possible that: A Professor can supervise several students with the same essay_topic. Different professors can supervise different student with the same essay_topic.
So we have a relationship essay(StudentID, EssayTopicID, ProfessorID).
But I don't see what are the primary keys now. Or what kind of relationship do we have here? I would guess n:1:1 (er model). But then, only StudentID would be the primary key of that table – what's actually wrong, because the student only could write one essay…

If you write down the functional dependencies for your restrictions, it helps to understand the situation:
(student, essay_topic) -> professor
(student, professor) -> essay_topic
You've got two overlapping candidate keys - (student, essay_topic) and (student, professor). You can choose either as primary key in the physical model, as long as you add a unique constraint for the other.
I suspect this is a situation that can't be exactly modeled in ER (yes, ER isn't a complete data model, unlike the relational model). I would leave out the cardinality indicators and include the FDs as a comment.
PS. Please don't confuse relationships between entities with relationships between tables. Relationships between entities are recorded IN tables as an association between (usually different) entity sets. Relationships between tables are foreign key constraints and enforce a subset restriction on two columns of the same entity set.

If you want your database engine to prevent adding multiple equal topics and professors per student, you will need a composite key / composite constraint over student_id + topic_id + professor_id. Have a look at this question:
How do I specify unique constraint for multiple columns in MySQL?

Related

Is it antipattern to create a junction table with more than two foreign keys?

I am designing a database for school management.
Here instead of a single school, there are multiple schools with their own students, classes, teachers and subjects.
Here is the requirements.
• A school can have many classes
• A class can have many sub classes
• Many Students can belong to a section of a class
• Many Teacher can belong to a section of a class
• Many Subjects can belongs to a section of a class
• School wants to manage classes
• School wants to manage sections
• School wants to manage subjects in a section of a class
• School wants to assign a teacher for a subject in a section of a class
• School can assign a student a section of a class
Also, some school can have classes as named One, Two, Three and Some may have First, Second and Third. Also same for sections or sub classes
For entities School and Teacher things are straight forward. Below is my approach for them.
School
--------------
id
name
...
Teacher
--------------
id
school_id
name
But I am facing problem while mapping classes and sections for a school.
I tried to make two other entities classes and sections and give them a foreign key of the school
SchoolClass
-----------------
school_id
class_name
...
SchoolSection
----------------
school_id
section_name
...
For mapping a school's class to all its section I created a junction table, as it will be many to many relationship.
SchoolClassSection
---------------------------------------------------------
school_class_id
school_section_id
But as I mentioned above I also need to add subjects and teachers to a section of the class so tried something like below.
SchoolClassSections
---------------------------------------------------------
school_class_id
school_section_id
subject_id
teacher_id
But now I ended up having four foreign keys in the junction table.
Is there no issues in having more than two foreign keys in a junciton table?
Also, I need to add students too, but I can't now figure it out How to move further for students relation for classes, sections?
One thing I could thing of like below
student
-----------
school_id
school_class_section_id // but if SchoolClassSections can have subject_id and teacher_id too it will become confusing
No, it is not an "antipattern". There are many examples where a junction table might have more than two foreign keys:
A doctor's appointment might have a doctor, a patient, and a clinic.
A retail order might have a customer, a location, and a payment type.
An online subscription might have a customer id, product, payment type, and source.
Those are just some examples from other domains (and they do not even include a date dimension). It is not uncommon for a table to have multiple foreign keys.
I didn't analyze your schema, due to time constaints here.
But there's no problem from either the relational point of view or the SQL point of view with a table or junction table having more than two foreign keys. In fact, that's pretty common.
Some concepts, especially OO concepts, do not fit well with SQL.
SQL has "only":
1:1 relationships (generally this should not be used)
1:many (implement via a link in one table to the other)
many:many (requires a separate 'junction' table)
In each case "1" can degenerate to "0" and "many" can degenerate to "1" or "0". Usually "0" is not represented explicitly but by the absence of rows.
To create schemas:
Think of what "entity" tables to have. (Student, Class, School, etc.)
Create relations, thinking in terms of 1:many and many:many.
Optionally, establish FOREIGN KEYs for the links. (For referential integrity; implicitly creates an INDEX)
Make sure the appropriate columns are INDEXed. (For performance)
Later...
Write the SELECTs, UPDATEs, etc.
Use those queries to decide whether other indexes are needed.
Your question is mainly about the many:many tables.
The basic many:many table has exactly 2 column (links to two other tables)
The basic has two composite indexes (PRIMARY KEY(a,b) and INDEX(b,a))
Sure, make it many:many:many (Not common, but reasonable)
Add columns for attributes about the relations (also not common, but OK)
Add composite indexes for the queries that depend on those attributes (for performance)
More discussion of many:many: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

Database Design: Primary key and many to many associations

This is my first database design of my home library. I have a question about how to implement the primary keys in each table, I am also interested to know if it is acceptable to have many tables associated with one foreign as I have with the many relationships with "contributor_id."
Not all of my tables have a primary key. If a primary key should NOT be the foreign key (as I have come to understand it) what could serve as a primary key in copy_info and book_info tables? I am not sure I have correctly implemented the intermediary tables where there many to many relationships might exist. Is this a situation where I should require a composite primary
key?
Maybe there are differing opinions on how to do this, but any insight would be appreciated. Where I am brand new to this, please excuse if my question is not sufficiently specific.
I just give few quick advices:
I understand the 4 tables on the left are intermediary tables between book_info and other 4 tables with translators info, authors info and so on; am I right? So is a many-to-many relationships (a book can have many authors and one authors has many books), but if you set up the tables like this every time you try to insert the same contributor for another book it will cause a duplicate key error! So, remove the keys from there.
the right way to assign a key to these aggregate tables with be to assign the key to both values (so you will never break the "uniqueness" constraint), BUT is completely unuseful (and a waste of space and Db resources) to assign keys in these simple aggregate tables
books and book_info is a one-to-one relationship? So it makes sense to split this in 2 separate tables ONLY for tidiness purposes (for example if you have a lot of fields and you want to separate them by some logical criteria)
books and book_info is another many-to-many relationship? In this case the "id" field as key is a correct solution, but is not correct to couple together the tables books and copy_info (better to couple the copy_info to the book_info, so you wil split it to two one-to-many relationship (easier to manage in this case)
i hope I helped a little, anyway you can easily solve it with little practice on the field.
I was misunderstanding how to implement a many-to-many relationship. Once I put in junction tables, my tables all had primary keys.
Updated Design

Designing a relationship with three entities where two entities have no relation

Trying to implement an ER model where I have entities:teacher,student,papers and relationship: publishes,advises. Both teacher and student can publish a paper but only a teacher can advise a paper. Should I duplicate publishes relationship for both student and teacher or can I make it look like a three-way relationship with having no relationship between teacher and student?
It sounds like you could model it like:
student(student_id, name, etc)
teacher(teacher_id, name, etc)
paper(paper_id, title, text, etc)
contributor(contributor_id, paper_id, contribution_type, contributor_type)
Where contribution type is an enum(publisher,adviser) and similarly contributor type is an enum(teacher,student)... or booleans is_publisher, is_adviser.
The drawback is that this doesn't permit foreign keys from contributor to student/teacher, and you don't have a rigid constraint from advisers to teachers. A table adviser(teacher_id, paper_id) allows a constraint on the advisers, but still doesn't allow constraints or foreign keys on student ids.
Another options might be to break it up as:
teacher_contribution(teacher_id, paper_id, is_adviser)
student_contribution(student_id, paper_id)
which would allow completely constraining the database to the intended model, but could be more difficult to query in some situations.
Any are acceptable. It depends to some extent on your particular application and how you intend to query the data.

Translating relationship attributes from ER diagram into SQL

Currently trying to get to grips with SQL for the first time, so I am working through a few problems. Here is a sample database spec:
Students (name, gender, course) do projects(title). Each project has
two supervisors (name, gender, department). All students do a project
but not all projects get taken. More than one student can do the same
project. Students meet one of their supervisors regular and these
meetings are recorded (date, time, student, supervisor, notes).
So far I've got an ER diagram drawn up which I think is correct:
I can get the basics (e.g. creating a Student table etc) but I'm having trouble getting my head around how to represent the relationships, specifically the meetings relationship, and how to represent it and its attributes in SQL. Should I instead create a 'meetings' entity?
Yes, you should create a Meeting entity to represent the many to many relationship between Student and Supervisor. In it you can relate to those tables using foreign keys that correspond to the those respective tables. In SQL it may look something like this:
Create table Meeting {
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
supervisor_id INT NOT NULL,
//rest of the fields...
FOREIGN KEY (student_id) REFERENCES Student(id)
FOREIGN KEY (supervisor_id) REFERENCES Supervisor(id)
}
You would also do the same thing for the Supervise between Project and Supervisor. Also you could use something called a composite key on your Meeting table, I guess it comes down to personal preference, I usually do it this way when representing many to many relationships. I'm not saying this is the syntax you will use, that depends on your database, this was just an example to point you in the right direction. Hope it helps.
Also for your diagram (I'm just guessing this is for a class) you might want to look into software such as visio or visual paradigm to create your ER diagram. While most people will be able to understand your current diagram, that's not correct modeling.
For fun I made a diagram based on your tables:
You would want an entity between Supervisor and Project if they are a many to many relationship. This is called an associative entity. I labeled mine SupervisorProject just so they are a little more clear.
Edit
Overlooked the fact that Student and project was a many to one, fixed that, sorry.
In response to Cohagen this stackoverflow post suggests that many to many relationships like Supervise can be represented by keeping the relationship table even if it has no attributes. In contrast the Do table lies between a many to one relationship and doesn't have attributes so we can get rid of it and simply add a foreign key reference to the project table in students.

Trouble deciding on identifying or non-identifying relationship

I've read this question: What's the difference between identifying and non-identifying relationships?
But I'm still not too sure...
What I have is three tables.
Users
Objects
Pictures
A user can own many objects and can also post many pictures per individual object.
My gut feeling tells me this is an identifying relationship, because I'll need the userID in the objects table and I'll need the objectID in the pictures tables...
Or am I wrong? The explanations in the other topic limit themselves to the theoretical explanation of the way the database interprets it after it's already been coded, not how the objects are connected in real life. I'm kinda confused as to how to make the decision of identifying versus non-identifying when thinking about how I'm going to build the database.
Both sound like identifying relationships to me. If you have heard the terms one-to-one or one-to-many, and many-to-many, one-to- relationships are identifying relationships, and many-to-many relationships are non-identifying relationships.
If the child identifies its parent, it is an identifying relationship. In the link you have given, if you have a phone number, you know who it belongs to (it only belongs to one).
If the child does not identify its parent, it is a non-identifying relationship. In the link, it mentions states. Think of a state as a row in a table representing mood. "Happy" doesn't identify a particular person, but many people.
Edit: Other real life examples:
A physical address is a non-identifying relationship, because many people may reside at one address. On the other hand, an email address is (usually considered) an identifying relationship.
A Social Security Number is an identifying relationship, because it only belongs to one person
Comments on Youtube videos are identifying relationships, because they only belong to one video.
An original of a painting only has one owner (identifying), while many people may own reprints of the painting (non-identifying).
I think that an easier way to visualize it is to ask yourself if the child record can exist without the parent. For example, an order line item requires an order header to exist. Thus, an order line item must have the order header identifier as part of its key and hence, this is an example of an identifying relationship.
On the other hand, telephone numbers can exist without ownership of a person, although a person may have several phone numbers. In this case, the person who owns the phone number is a non-key or non-identifying relationship since the phone numbers can exist irrespective of the owner person (hence, the phone number owner person can be null whereas in the order line item example, the order header identifier cannot be null.
NickC Said: one-to- relationships are identifying relationships, and many-to-many relationships are non-identifying relationships
The explanation seems totally wrong to me. You can have:
Ono-to-One Non-identifying Relationships
One-to-Many Non-identifying Relationships
One-to-One Identifying Relationships
One-to-Many Identifying Relationships
Many-to-Many Identifying Relationships
Imagine you have the following tables: customer, products and feedback. All of them are based on the customer_id which exists on the cutomer table. So, by NickC definition there shouldn't be exists any kind of Many-to-Many Identifying Relationships, however in my example, you can clearly see that: A Feedback can exists only if the relevant Product exists and has been bought by the Customer, so Customer, Products and Feedback should be Identifying.
You can take a look at MySQL Manual, explaining how to add Foreign Keys on MySQL Workbench as well.
Mahdi, your instincts are correct. This is a duplicate question and this up-voted answer is not correct or complete.
Look at the top two answers here:
difference between identifying non-identifying
Identifying vs non-identifying has nothing to do with identity.
Simply ask yourself can the child record exist without the parent? If the answer is yes, the it is non-identifying.
The core issue whether the primary key of the child includes the foreign key of the parent. In the non-identifying relationship the child's primary key (PK) cannot include the foreign key (FK).
Ask yourself this question
Can the child record exist without the parent record?
If the child can exist without the parent, then the relationship is non-identifying. (Thank you MontrealDevOne for stating it more clearly)
One-to-one identifying relationship
Social security numbers fit nicely in to this category. Let's imagine for example that social security numbers cannot exist with out a person (perhaps they can in reality, but not in our database) The person_id would be the PK for the person table, including columns such as a name and address. (let's keep it simple). The social_security_number table would include the ssn column and the person_id column as a foreign key. Since this FK can be used as the PK for the social_security_number table it is an identifying relationship.
One-to-one non-identifying relationship
At a large office complex you might have an office table that includes the room numbers by floor and building number with a PK, and a separate employee table. The employee table (child) has a FK which is the office_id column from the office table PK. While each employee has only one office and (for this example) every office only has one employee this is a non-identifying relationship since offices can exist without employees, and employees can change offices or work in the field.
One-to-many relationships
One-to-many relationships can be categorized easily by asking the same question.
Many-to-many relationships
Many-to-many relationships are always identifying relationships. This may seem counter intuitive, but bear with me. Take two tables libary and books, each library has many books, and a copy of each book exists in many libraries.
Here's what makes it and identifying relationship:
In order to implement this you need a linking table with two columns which are the primary keys of each table. Call them the library_id column and the ISBN column. This new linking table has no separate primary key, but wait! The foreign keys become a multi-column primary key for the linking table since duplicate records in the linking table would be meaningless. The links cannot exist with out the parents; therefore, this is an identifying relationship. I know, yuck right?
Most of the time the type of relationship does not matter.
All that said, usually you don't have to worry about which you have. Just assign the proper primary and foreign keys to each table and the relationship will discover itself.
EDIT: NicoleC, I read the answer you linked and it does agree with mine. I take his point about SSN, and agree that is a bad example. I'll try to think up another clearer example there. However if we start to use real-world analogies in defining a database relationship the analogies always break down. It matters not, whether an SSN identifies a person, it matters whether you used it as a foreign key.