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));
Related
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.
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 can we make a constraint on the database, so that only one entity fits in a desired position?
For example, we want to have a president for the Country database.
How can we define the "is-president" attributes so that only one entry can have the "true" value.
You can do it when inserting the data to your table. If you want to add a president, first check whether there is a president or not.
You're better off modelling this in a different way - for example having a Countries table, a People table, and then a Presidents table which has a foreign key to the Countries table, and a foreign key to the People table.
You can then add a unique constraint on the composite value of both foreign keys to ensure only 1 person exists per country within the Presidents table.
should I signal the foreign key in a database column name?
FKOrder vs. FK_Order vs. Order
The short answer is no - don't put "FK" in column names of foreign key columns. You can still signal the intent of the column though, here's how I do it:
Naming foreign key columns
It depends on your naming convention for the target of the FK. If you have Id, then I'd prepend the table name when creating FK columns.
Example 1:
For table User with PK Id and table Workitem with user ID FK, I'd call the column Workitem.UserId.
If there were more than one FK between the same tables, I'd make this clear in the column name:
Example 2:
For table User with PK Id and table Workitem with "assigned to user ID" and "created by user ID" FKs, I'd call the columns Workitem.CreatedByUserId and Workitem.AssignedToUserId.
If your naming convention for PKs is more like UserId, then you'd factor that into the above examples so as not to end up with UserUserId.
Naming foreign key constraints
This is mine:
FK_childtablename_[differentiator]parenttablename
The differentiator is used when there is more than one FK between the same two tables (e.g. CreatedByUserId and AssignedToUserId). Often I use the child table's column name for this.
Example 1:
Given tables: Workitem and User
Where User has CreatedByUserId and AssignedToUserId
Foreign key names are FK_Workitem_User_CreatedByUser and FK_Workitem_AssignedToUser
I use double-underscores if tables/columns have underscores in the name:
Example 2:
Given tables: work_item and user
Where user has created_by_user_id and assigned_to_user_id
Foreign key names are FK_work_item__created_by_user and FK_work_item__assigned_to_user
Is usual to name the foreign key fields with an ID (IDORDER, IDPERSON, ...), if you have a table called PERSONS and another CITIES, if one person is in certain city, CITIES has an IDCITY field (K), PERSONS has a IDPERSON (K), and other field IDCITY (FK).
Hope this answers your question. I mean, a foreign key is only foreign when it's in other table, but not in theirs. But it's a good practice to name always the same to the same fields, even if they are in other tables, as a foreign key.
You shouldn't.
If a column becomes a foreign key later, you will have to change the column name, breaking all the scripts that are using it.
If there are multiple foreign keys, you don't know which column belongs to which key, so the only information you gain is that the column is a foreign key, but you already know it by looking at the keys.
Usually I name the foreign key column the same as the primary key, so I know immediately where the key maps.
I normally use the same name as the referenced column in the table holding the FK.
Only if this is potentially confusing (or a column with this name already exists, say id), would I be more explicit. In such a case, adding the entity type name before the rest - say ProductId.
My style is slightly different:
fk_table_column
eg: fk_user_id that is foreign key to User table on id column. I do not use any capital latter.
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.