Many to Many with Variable Foreign Key - database

I am drawing an ERD diagram for the following scenario:
A user can have one or many subscriptions. A tv show can be on one or many subscriptions. A movie can also be on one or many subscriptions. The confusion comes from the foreign keys. How would I map it out? What would be the foreign key name etc? A subscription can be linked to a movie, OR a tv show but cannot have both. Is it better to just create a bridge table for each entity type e.g. have a TVSubscription table for TVShows, and a MovieSubscrption table for movies?
I'm confused on how a subscription have be linked to multiple entities.

A foreign key must be primary key on another table. So basically, your subscription table must have more than one foreign key. The correct structure to your subscription table should be something like:
id (PK)
user_id (FK referencing USER PK)
movie_id (FK referencing MOVIE PK)
tv_show_id (FK referencing TV SHOW PK)
This structure should handle your problem.

Related

One-to-many relationship: composite primary key or single primary key?

I have a table person containing personal info, and I have another table person_contact to store contact information about that person (type shows if it's a phone record or email record, and record contains the actual phone number or email address).
I have designed the schema like this:
In person_contact I have declared pcont_id and person_id as PK while person_id is a FK referencing person.person_id. Do I need the PK pcont_id at all? When should I use a single PK in a one-to-many relationship and when is it better to use composite PK?
You don't need person_id as a part of your primary key in person_contact table. pcont_id should be the primary key if you have a one to many relationship between the two tables.
Do I need the PK pcont_id at all?
I suggest, it should be there and should be primary key of your table assuming you can have multiple contacts for one person.
If one person can have only one contact, in that case you don't need that table itself, you can store the data directly in the person table.
If you still want to store it separately then you don't need pcont_id column, your person_id column should be marked as primary key.
When should I use a single PK in a one-to-many relationship and when
is it better to use composite PK?
Composite primary key is used when you have a junction table/associative table to map a many-to-many relationship. In case of one-to-many relationship you don't need composite primary key with the foreign key column.

Make a entry mandatory if exist in a table

I have the next design doubt:
I have athlete entity, the athlete can have many nationalities, so I have second table called countries. Then between athlete and countries there is a many-to-many relationship. I create another table athlete_country to resolve the many-to-many relationship.
My question: Is there a way to achieve that athlete_country entry be mandatory for any entry in the athlete table?
I am working on postgresql. Is there a way in another database server?
No, this is not possible to do it this way for logical reason: athlete_country tables references athlete table, and if you do back reference (in fact you can do it) you will not be able to insert any row in either table because each row should reference to the row in another table, which isn't inserted yet.
The solution is to use many-to-one relationship in addition to many-to-many which you have described. For example, you can add "primary_country" field to athlete table which references directly to the country table. In that case you can be sure that any athlete has relationship with at least one country, specified in "primary_country" field and, optionally, with other countries listed in the athlete_country table.
create table country(id serial primary key, name text);
create table athlete(id serial primary key, name text, primary_country int references country(id));
create table athlete_country(athlete_id int references athlete(id), country_id int references country(id), primary key (athlete_id, country_id));

Foreign key for different entities

Say if a real life operation like loaning a library book is to be performed on two entities Teacher and Student. And the operation details are present in a table like Loans or Transaction. How do I define a foreign key in the Loans table for both Teacher and Student which have different schemes for primary keys? (student has 6digit key but teacher has 4 digit)
A similar question arises when a hospital database system Appointment table attempts to link to both an Employee table and EmployeeRelatives table using a foreign key, where both Employees of the hospital and their relatives are to be given free treatment. How does one specify format of foreign key in Appointments table?
A foreign key can reference only one table.
My solution in these cases is to introduce an additional table (People or whatever name you prefer) which contains all the IDs of Teacher and Student. Teacher and Student can also have the People table key as foreign key.
You can find other possible solutions here:
Foreign Key to multiple tables

Entity Framework won't resolve PK-FK relationship with composite primary key?

I'm trying to set up an EDM on an existing SQL Server infrastructure, and came across a problem.
The EDM will not resolve a PK-FK relationship to a composite foreign key.
My DB table structure looks something like this (names changed to protect the innocent):
I have a PERSONS table containing an INT column called PerID (PK)
I have an OFFICE table containing an INT column called OffID (PK)
I am tying these tables together using a table called OFFICEPERSONS, creating a many-to-many relationship between PERSONS and OFFICE. This table has two INT columns, PerID and OffID, which together form a composite primary key.
I have a table called OFFICELOCATION that contains two INT columns, LocID and OffID. These two columns comprise a composite primary key. Additionally, OffID is also a FK to the OFFICE table.
Finally, I have a table called OFFICEPERSONSLOCATION. This table has three INT columns: PerID, OffID, and LocID. All three columns comprise a composite primary key. LocID and OffID provide a FK relationship to OFFICELOCATION, and OffID and PerID provide a FK relationship to OFFICEPERSONS.
With me so far? Hopefully, I haven't lost you yet. When all is said and done, my structure looks like this:
This structure works great in SQL Server. In EDM? Not so much. It will NOT allow me to construct the relation between OFFICEPERSONSLOCATION and OFFICEPERSONS. I get the following error:
Error 6037: Foreign key constraint 'FK_OFFICEPERSONSLOCATION_OFFICEPERSONS' has been omitted from the storage model. Column 'OffID' of table 'Model.Store.OFFICEPERSONSLOCATION' is a foreign key participating in multiple relationships. A one-to-one Entity Model will not validate since data inconsistency is possible.
Huh? Data inconsistency?!? How?
How do I get my entity framework to recognize this?
I agree that it is the entity framework's problem, and the problem is stupid. Even if you have the UPDATE CASCADE to "no action", it is not like you could create an inconsistency, but no, it claims that you can somehow.
In any case, in this situation, if you are willing to use surrogate keys instead of composite keys, you can get around this, because the only place to change the ID reference is in the main table.
In this case, OffID could be "inconsistent", but by using ID's in the OFFICEPERSONS and OFFICELOCATIONS tables (and therefore reference in OFFICEPERSONSLOCATION), you are forced to have the OffId managed in its primary table.

How to insert multiple rows for a single primary key?

I have a table named 'Patient_detail'. There are 4 columns in this table. They are:
patient_id primary key(not null)
visit_serial_ID primary key(not null)
examination
plan
Now, how can I insert multiple records in 'examination' and 'plan' column against the single primary key 'patient_id' and 'visit_serial_ID' of the table 'Patient_detail'?
The datatypes of the fields are as follows:
patient_id: number(11)
visit_serial_ID: number(5)
examination: varchar2(50)
plan: varchar2(50)
You can't (that's the whole point of a primary key - you have one row per value). You need to split this into a couple of tables, one for visits and one for patients. The visit table would have a foreign key relationship to the patient table's primary key column.
EDIT
You need to think about what actual real-life things you are representing, and how they interrelate. For each separate real-life thing, you would usually have a separate table. This allows the one-to-one, many-to-one, many-to-many relationships that you are after. For instance, you are representing a patient who has a visit, during which there are a number of examinations, each of which has a corresponding plan (is this correct?). You should therefore have a patient table containing patient data, a visit table, containing visit data, and an examination table containing examination data, and maybe even a plan table containing plan data.
The visit table has a many-to-one relationship with the patient table (a patient can visit a number of time). To achieve this, it should have a foreign key to the patient_id column. Similarly, the examination table has a many-to-one relationship with the visit table, so, again, it should have a foreign key to the visit table's primary key.
There are further ways that the can be separated. As Sascha said, look up normalisation.
You can do this but your primary key would cease to be a primary key and you data would be denormalized. The best way to do this would be to split this table into two separate tables like this:
Patients
----------
PatientId
Visits
----------
VisitSerialId
Examination
Pland
PatientId
Notice that the Visits table has a foreign key realtionship to the Patients table. This will allow you to have the 1:M relationship you are looking for.
You can't. That's what a primary key is - something that is unique to every row. You would need a separate table with its own primary key, and with a foreign key relationship to this table, in order to store multiple entries. This would then be a straightforward one-to-many relationship.
As darasd said you can't. What you're looking for is call normalization.

Resources