Database Design: Primary key and many to many associations - mysql

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

Related

database design two tables vs join table, which is better

I have two tables matches and tournaments with below structure,
MATCH
MATCH_ID
PLAYER_ID_1
PLAYER_ID_2
RESULT
TOURNAMENT_ID
and
TOURNAMENT
TOURNAMENT_ID
NAME
OTHER_DETAILS
with one tournament will have multiple matches
and a match may or may not have tournament id
use Cases:
retrieve all matches
retrieve all matches by tournaments
Is it good to have tournament id in match table? Or should I create a separate joining table for tournament and match mapping? Which will have good performance when the volume increases?
TOURNAMENT_ID has a 1:M relationship to MATCH. It seems to be a straightforward foreign key. The standard way of implementing foreign keys - even optional foreign keys - is a column on the child table with a foreign key constraint. This would support both your use cases.
A separate table would normally be a head scratcher. I say "normally" because there are schools of thought which abominate NULL columns in databases; either for practical reasons - NULLs can do weird things to our code and need wrangling - and academic reasons - NULL is contrary to Relational Algebra. So, if you have a data model which forbids the use of nulls you will need a TOURNAMENT_MATCH table to hold Matches which are part of a Tournament. It also would be likely to perform slightly worse than a foreign key column on MATCH, but unless you have a vast amount of data you won't notice the difference.
There is a use case for join tables (also known as junction or intersection tables) and that is implementing many-to-many relationships. Suppose we add a third table to the mix, PLAYER. A Player can participate in many Tournaments and a Tournament has many Players. Classic M:N relationship. So we can resolve it with a join table REGISTERED_PLAYER. which as a compound key of (TOURNAMENT_ID,PLAYER_ID) and the appropriate foreign keys to TOURNAMENT and PLAYER.
For the sake of completeness I will mention Link tables from Data Vault modelling. This is an interesting modelling technique for Data Warehouses, where - gross simplification alert - tables are defined as Hubs (business and technical keys) and Satellites (immutable attribute records). This approach allows for the capture of data changes over time. Foreign key relationships between Hubs are implemented through Link tables, to support changing relationships over time.
There are several benefits to Data Vault for wrangling large amounts of data in a time-sensitive fashion but an easy-to-understand physical data model isn't one of them. Anyway, find out more.
The simple rule: for one-to-many mapping always prefer a foreign key association to a join table association.
It is hard to control a join table using a standard #OneToMany Hibernate mapping — you can't just delete rows from a join table, or add an additional row. You will need to use list on the Tournament side to do things like that. Another option is to use an additional entity for a join table.
Note: Match can has a tournaments list too, but looks like Tournament is the owner of the association.
A few opinions have been offered in other answers, here is mine.
You do NOT want a separate join table, you would only need that if a Match can be in multiple Tournaments. In your example, just use a foreign key.
The only other suggestion is that if the Match is not part of a Tournament then it is not actually "unknown" which is the meaning of NULL, it is actually something else like "Individual Match". So consider adding a row to your Tournament table, maybe using a known key like 0 or -1, and using that for matches that are not part of a tournament.

How can I join two tables with two different primary keys into another table?

I have two tables: students and courses, assuming that each student can be in more than one course and that each course can have more than one student.
[Table Students] [Table Courses]
id(PK) id(PK)
name name
age duration
etc... etc...
and what I want to do it is to relate both tables into another table, for example, studying, in which I will store the course or courses that is doing each student. Like this:
[Table studying]
idStudent
idCourse
What I have deduced
I think that idStudent and idCourse should be foreign keys because the information it is stored in students and courses respectively with an unique primary key and to respect the consistency of the database. It cannot exist a relation without information neither of the student nor the course or just without the information of one of them.
I also know that some tables has two primary keys to allow that in the table could exist more than one repeated value of a primary key, but not of both primary keys at the same time.
My questions
These ids (idStudent, idCourse). Have to be primary keys or foreign keys?
Should the table studying has another column with an ID?
Is my deduction in the good way?
P.S: I do not need sql statements, I just need help to clarify my confusion.
Thanks in advance!
These ids (idStudent, idCourse). Have to be primary keys or foreign keys?
You want them to be foreign keys, because the existence of each record on your third table depends on the availability of the first, that is, there cannot be a "Student Course" or a "Course with Students" without either the course or the student. It could (if you don't make those keys) but you would break referential integrity
On the other hand, having FK's is usually a good thing because you make sure that you don't remove dependable records by mistake (which is what the constraint is for on the first place) unless you did something like cascade deleting
Should the table studying has another column with an ID?
No, it does not have to but again, sometimes it is a good practice because some software like Object Relational Mappers, Diagram Software, etc. may rely on the fact that they always needs a by-convention primary key. Some others don't even support composite keys so while it is not mandatory it can help in the future and it does not hurt. Of course this all depends on what you are using the database for and how (pure SQL, which engine you use, if you use it with a framework etc.)
Is my deduction in the good way?
All is relative. But I think your logic is good. My advice is that you always design your data schemas as flexible as you can because if a project grows its harder (and more costly) to do those changes down the road. Invest time on thinking how you may expand your application functionality and think if the schema will adapt to it.
Your deduction is correct.
In fact, you should have a composite primary key consisting of both (idStudent, idCourse) columns, because this tuple is the identifier of row in the table, you do not need additional ID column (of course, you can also take that approach to add additional ID column that would be your primary key, but you do not need it if one student can have one course assigned only once)
To respect the integrity, both columns (separately) should be foreign keys - idStudent should be referencing id column of Students table and idCourse should reference id column of Courses table.
If you like you can make them primary keys on studying table. But this is unnecesary, because relation (role of studying table) is many to many and this kind of table dont need primary keys. You need to know that also when you make them pk (pair of student id and course id) , thats mean that theee could be only one pair of each, thats equivalent to constrain unique - student can take a course only ones. In the future you maybe would like to add to this table start_date and this kind of pk could be a problem, you will need to modify them.

Best Practice: Separate Tables for Separate Info on Same User

I am designing a database for student information. I wish to implement the best practices regarding separate tables and use of Primary and Foreign Keys.
Let's say I have the following tables (High Level):
Users
Student Information
Student Transcripts
Student Records
There will be different users with different levels. Also, the information in Student Info/Transcripts/Records will all have a Foreign Key with the ID that's in Users.
SO, it would be dumb to just clump all the tables into one big table, wouldn't it? Is it a good idea to keep all this information separate and just use Primary/Foreign keys to link things together, as well as maybe Joins? I just personally think a big table would be quite messy and through this way, it allows one to keep similar data together with its own kind.
Thanks for all input on the matter!

Are foreign keys used in a "link" table?

Quick question about DB design! In this example there are users and schedules. Each user can have many schedules and each schedule can belong to many users.
I have two tables, 'user' and 'schedule', that each have a unique identifier/primary key (user_id and schedule_id): these tables have a many-to-many relationship.
This is where I am unsure/inexperienced: In order to connect them together and adhere to good db design, I want to create a link table that has two columns, user_id and schedule_id. I plan to make these both primary keys (therefore a composite key). However, do I also add two foreign keys, one on user_id linked to the 'user' table and one on schedule_id linked to the 'schedule' table?
TLDR: I plan to use a composite key in 2-column 'link' table that connects two tables. Should/Do I also need to make those into foreign keys?
PKs and FKs serve different purposes. In a link table, you need the PK to preserve uniqueness of the data. However, if you do not also create the FKs then you may end up with data integrity problems because the ID could be deleted from the original table and not the link table.
Sometimes people think they can get away without the FKs because they will enforce data integrity through the application. Almost always this is because they find it annoying when the constraints won't let them do something they want to do. Of course that is the purpose of the constraint, to prevent users and developers from doing things they should not. Data integrity must be preserved through the database; it is too important to risk letting the application handle it. I have seen a lot of data from hundreds of databases and the ones with the worst data are invariably the ones where the devs thought they could manage stuff like table relationships through the application. There are always holes when you do this and eventually they come back to bite you and then they can be very difficult to fix properly.

One-to-One Relation or Use the Same Table?

I have the following tables created:
Animes(id,title,date), Comics(id,title,date), TVSeries(id,title,season,episode,date)
Some of them have already foreign keys (for one-to-many or many-to-many relations) of directors, genres, articles and so on.
Now i would like to create two more tables Reviews(id,rating,date) and Posts(id,thumbid,articleid,reviewid).
A review is about one Anime and/or Comic TVSerie and vise-versa but properties of a review may be in more than one table. Its the same about a posts.
Is this a typical example of one-to-one relation in separate table or is it more efficient to add more properties to the existing tables?
So more tables and relations or less tables more columns?
Thank you and i hope my question isnt that stupid but im a bit confused.
In my view, It is better to avoid foreign key relationship for one-to-one relationship. It is best suitable for one - many relationships.
I'm not exactly sure what your requirements are, but the choices are as follows:
Have Reviews have 2 columns, either being a foreign key to the applicable table, can be NULL. This is really for when a single review can be about both.
Have a ReviewsComics and ReviewsAnime table. You'd then have all the fields from Reviews in each table (and no Reviews table).
An alternative (2) is to use them in conjunction with a Reviews table, then those 2 tables only has 2 fields which are foreign keys to Reviews and Comics/Anime respectively (thus no direct link between Reviews and Comics/Anime).
Have a base table to which Anime and Comics are linked to 1-to-1 and have reviews link to that table instead.
(Edit) If all the fields are all going to be the same (or similar) for Anime/Comics, you can merge them into a single table and add a type field, indicating Anime/Comics, then the problem goes away. This is similar to the base table option.
EDIT: The 2 reviews tables will probably give the best performance (unless you want to select all reviews for either, often), but with proper indices the performance shouldn't be an issue with any of the above.