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

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.

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 do I add mulltiple records and avoid using multi-field values?

I'm creating a database for personnel records and trying to ease record creation for the user and avoid a kludgy solution. The tables are:
people:
people_id,
person_name,
person_category_id
person_category:
person_category_id,
person type
document_requirement:
document_requirement_id,
document_requirement_name,
person_category_id,
document_section_id
document_section:
document_section_id,
document_section
I've created an append query (inner join) that populates a table caLLed document_repository which contains all of the required documents for all of the people. (I use a primary key composed of people_ID & document_id to avoid duplicates when the append query runs.) Here is the document_repository table.
document_respository:
document_repository_id,
people_id,
person category_id,
document_id,
document_section_id,
document_attachment
I'd like to be able to allow the user to create a document requirement that is applicable to multiple person categories. I understand I should avoid multi field values, which doesn't work anyway with inner joins. For example, if people categories include doctors and nurses, I'd like to be able to create a new document requirement that applies to both people categories (e.g., doctors and nurses), without having to create two separate document requirements.
More information needed?
Suggestions on design changes and/or queries?
Thanks!
snapshot of tables and relationships
What you describe is a many to many relationship. Each document requirement can be applicable to multiple person categories and different document requirements can be applicable to the same person category.
To have a many to many relationship between two entities (tables) in your database, you need another table to relate them. This additional table contains the primary key of both tables and each record in this table represents a link between the two entities.
Your naming is different between your text and your diagram, but I'll assume you want to have document_requirement records that can link to zero or more person_category records.
You need a table which for example could be called document_requirement_person_category and contains the following fields:
document_requirement_id - foreign key referencing PK of document_requirement
person_category_id - foreign key referencing PK of person_category
You then add a record to this link table for each person category that relates to each document requirement.
Edit: BTW, (if I'm reading your schema correctly), you already have a many to many relationship in your schema: document_repository allows a relationship between multiple people and a document requirement as well as multiple document requirements and a person. That's a many to many relationship.

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

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!

Model a table that can have a relationship with several tables

I have a table called 'notes', on this table I need to track who made that note, but the problem is that the creator of the note can be a user stored in one of three possible tables:
users
leads
managers
I have though of simply create three fields on 'notes' to represent the three possible relations: note.user, note.lead, note.manager
With this approach I would be forced to create three table joins when requesting the notes to gather the creators information, and I don't think that is the way to go, so I would like to hear your ideas or comments and what would be the best approach on this.
For me personally this smells like a design problem on a totally different part of the schema: Are manageers not users? Do leads carry person information?
With any approach that creates a relation between one column and one of three others, you will need three joins for the select. If you can't rectify the underlying problem, I recommend you use
note_type ENUM('users','leads','managers')
as an additional field and
SELECT
...
IFNULL(users.name(IFNULL(managers.name,leads.name))) AS name
..
FROM notes
LEFT JOIN users ON notes.note_type='users' AND users.id=notes.note_source
LEFT JOIN managers ON notes.note_type='managers' AND managers.id=notes.note_source
LEFT JOIN leads ON notes.note_type='leads' AND leads.id=notes.note_source
...
for the query
I think you need to abstract out the concept of a user id, so that it does not depend on their role. The author of a note could then be specified by the user id.
Users could be assigned roles, and maybe more than one.
The correct way to structure this would be to pull all common data out of users, leads, and managers. Unify this data into a "contact" table. Then if you want to get all notes for a given manager:
managers->contacts->notes
for a lead:
leads->contacts->notes
Notice your original post: "the problem is that the creator of the note can be a user stored in one of three possible tables"
From the structure of your sentence you even admit that all these entities have something in common; they are all users. Why not make the DB reflect this?
you have to model a parent table for the three tables you already have. Define a table that depicts generally user, leads and manager tables. Something like "Person". So you have all of the ids of the three tables and any common attributes on the Person table. And when you must define the relationship you put the foreign id "Person_ID" on the note table. And when you model user, leads and manager tables you also put the primary key as a foreign key to the Person table.
So you would have something like this:
Table users:
Users(
person_id primary key
...(attributes of Users)
foreign key person_id references Person.person_id
)
This model i depict is common to any relational model you have to model using parents and childs