Database relation in 3NF? - database

I have following relation. A company has several employees. Each employee is defined by its employee number ENr and he is living on an address EAddress with a ZipCode ZZipCode. The City with the ZipCode is an own table because otherwise there is redundancy in table Employee. Therefore ZZipCode is a foreign key in Employee.
A Group is defined by its GGroupId, therefore that is the primary key. Each group has one group leader which can be any employee. Therefore ENr is a foreign key.
Each employee can work on none, one or more groups. For this reason the table GroupMember exists where the the tuple ENr and GGroupID define the primary key and both are foreign keys (I cannot do both, bold and italic).
And last, a product is defined by its product id PId and is associated to a group GGroupID.
Well here are the relations for that written description.
Employe(ENr, EName, EGender, EAddress, ZZipCode, ESocNr,
ESalery) Group(GGroupId, GName, GCostNr, ENr)
GroupMember(ENr, GGroupID) #both members are foreign keys
too! Product(PId, PName, PPrice, GGRoupId)
Zip(ZZipCode, ZCityName, SStateID) State(SStateID,
SStateName)
For clarification: bold members are primary keys and italic members are foreign keys.
I tried to put that relation into 3NF. Can anyone confirm that this is right?

This seems to be good and normalised. I dont see any further division of the tables.

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.

Add the attribute of a 1 to many relationship on the many side too?

I want to make an ER diagram involving a 1 to many relationship. Should I add the attribute of the relationship on the N side too? And if possible write the correct ER diagram.
Take a simple example of many people working in one department with a constraint that a single person can work only in one department. That makes department connected to people in a one-to-many fashion.
The simplest way to represent this is to add the primary key of you department table as a foreign key in your people table.
The schema will look something like this
DEPARTMENT (dept_no, dept_name, dept_location,....)
PEOPLE (p_no, dept_works, p_name, p_dob,....)
Where, dept_works in PEOPLE table is the foreign key that references the dept_no Primary key in the DEPARTMENTS table. This way you can store the ID of the department for each person in which he/she works.

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

Database Design for student tracking system

EDIT: my revised Entity relationship diagram
A Student can have many contact times but this does not relate to what course they are on. So the courseID in tblContact was unnecessary, so I used to Primary keys in tblStudent relating to the grade for a particular tutor marked assignment and the course a particular student is on with that TMA.
Phew
http://i.imgur.com/cf3td.png
/Edit
My Old ERD
note that StudID and CourseID are a merged compound primary key
My question: Should I have studID and courseID in tblContact? or should I just have StudID, because I'm using a compound primary key I thought I should have both values in tblContact and tblStudentTMA?
Is this right?
The answer depends on whether the contact is related to a course or not.
If it relates to a course then you need some way of identifying the Course from the contact, but you can link to the tblCourse table from tblContact.
My preference for a many-many table is to use a separate primary key in your example StudentCourseID, which is a Identity column, this removes the need to store multiple foreign keys in a related table.
The primary key in tblContact has to have at least two columns. One of them has to be StudID.
It has to have at least two columns, because you need to store more than one contact per student. One of the columns has to be StudID to guarantee the contact row refers to an actual student. The second column probably needs to be DateOfContact.
A primary key {StudID, DateOfContact} allows one contact per student per day. If you use {StudID, TimeOfContact} instead--use a timestamp instead of a date--you can have more than one contact per student per day.
In addition to that, if every row in tblContact must refer to both a student and to one of that student's courses, then you should probably include CourseID in the primary key. You also need a foreign key reference from tblContact (StudID, CourseID) to tblStudentCourse (StudID, CourseID).
If it's not necessary for every row in tblContact to refer to a course, then tblContact.CourseID should be nullable, and it shouldn't be part of the primary key. But you should still have a foreign key reference from tblContact (StudID, CourseID) to tblStudentCourse (StudID, CourseID).

Database column naming for foreign key

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.

Resources