Database Design Correct Practice - sql

I've come across a small issue that probably pretty common, but that I've no idea how to search for. For example, say we have a database with the following tables:
Table of Exams - ExamID, Name
Table of Exam Questions - ExamID, QuestionID, Name
Should I make QuestionIDs be unique? I could make them unique for every ExamID, or I could just make QuestionIDs never repeat. Are there any advantages/disadvantages to doing either? Also, what should the primary keys be in both scenarios?

Kind of depends.
There are a lot of possibilities with no real "right" and "wrong".
My thoughts would be to probably separate it out into another table, so that the question could be reused across exams
Exam
----
ExamId int primary key,
Name varchar(500)
Questions
----
QuestionId int primary key,
Text varchar(500)
ExamQuestions
----
Id int primary key, -- this is optional, i just like "simple" primary keys rather than composite.
ExamId int FK, -- potentially create a unique constraint on examId/questionId
QuestionId int FK, -- potentially create a unique constraint on examId/questionId
questionOrder int -- this would allow a "ordering" of exam questions on a per exam basis.

Make ExamId as unique , because An Exam would not repeat again and again, but Question can repeat in the every exam.
Example : Term End Exam 2014 will not happen again in the next year , same question of Normalization may ask again and again.

If a question belongs exclusively to one exam you would make it unique for that exam. If you expect to see the question on different exams then it can't be dependent on the exam for uniqueness, it would get its key values generated independently of the exam.
An example of a case where an ID would be unique only for another entity would be an order/line item relationship, where a customer places an order that can have multiple line items. The line item has no meaning apart from the order that it belongs to, so you could identify the line items by an order id and a line item number that started from 0 for each order.

The important question isn't whether or not question ID should be unique. The important question is, "What are the semantics of the relationship between Exam and Question?" The answer to that tells us what the primary key of the question table should be.
Your Question table has a foreign key relationship with the Exam table that identifies the [one] exam to which a question belongs. It is the nature of that relationship that matters.
A non-identifying relationship is one in which the dependent entity (Question, in this case) can exist independently of the related "parent" entity (Table, in this case). One indication of this is whether a Question can be moved from one Exam to another, or if a Question need not belong to an Exam at all. If so, the primary key of the Question table should be simply the question id itself, which should therefore be unique and non-nullable.
Whether the Exam ID is nullable or not is dependent on the cardinality of the relationship
from Question to Exam: is it one-to-one (non-nullable) or zero-to-one (nullable).
An identifying relationship is one in which the dependent entity (Question) exists only within the context of the related "parent" entity (Table). If so, the primary key of the Question table should be compound, incorporating the Exam ID (foreign key to the Exam table) as well as the Question ID, with both Exam ID and Question ID non-nullable.
This constrains the Question ID to be unique within the scope of an Exam ID: whether it is
unique across the entire table or not doesn't really matter much at this point, since you need
the Exam ID and the Question ID to identify a particular question.

There are 2 tables
Exams - ExamID, Name to store exam information.
Exam Questions - ExamID, QuestionID, Name to store questions information with a foreign key from Exams table
This means that you are trying to represent a one to many relationship between Exams and Exam Questions tables meaning that a Exam has many Questions but a Question belongs to one and only one Exam.
If this is correct then make QuestionIDs primary Key in the Exam Questions table.
If this is not correct and a Exam has many Questions and Question belongs to many Exams then it is a many to many relationship. In this case you should have another Junction table for the many to many relationship. This the three tables would be
Exams - ExamID, Name to store exam information with ExamID as primary key
Exam Questions - QuestionID, Name to store questions information with QuestionID as primary key
Exam Questions Relationship - ExamID, QuestionID to represent the many to many relationship with a foreign key from Exams table and a foreign key from Exams Questions table

Related

How to implement ER Relationships :One to one, One To Many, Many to Many in Oracle?

Perhaps, this could seem like the basics of database design.But,certainly i find these concepts a lil tricky in the sense that how they relate to each other.
Theory as per my understanding.
One to One :
When each particular entity has one record.
One to Many :
When each particular entity has many record
Many to Many :
Multiple entities have multiple records.
As per the above if i could relate an example as
ONE TO ONE
Each employee having a unique passport number.
Table Employee
Empid(pk)
empname
passpordid(fk to passport)
Table passport
passportid(pk)
passportno
ONE TO MANY
An organisation having multiple employees
TABLE ORGANISATION
ORGID (PK)
ORGNAME
EMPID (FK TO EMPLOYEE)
TABLE EMPLOYEE
EMPID (PK)
EMPNAME
SALARY
This is the part that i want to know more that is many to many. I mean if we see one to many here. As a whole it could be said as many to many as many organisations having many employees but does that mean the whole relationship is many to many not one to many or one to many is a subset of many to many in the above example.
I wanna know the difference mainly between one to many and many to many both theoritically and by implementation.
An example of a many-to-many relationship would be EMPLOYEES and SKILLS, where SKILLS are things like "SQL", "Javascript", "Management" etc. An employee may have many skills (e.g. may know SQL and Javascript), and a particular skill by be possessed by many employees (e.g. Jack and Jill both know SQL).
In a database like Oracle, you need a third table to express the many-to-many relationship between EMPLOYEES and SKILLS:
create table EMPLOYEE_SKILLS
( empid references EMPLOYEES
, skillid references SKILLS
, constraint EMPLOYEE_SKILLS_PK primary key (empid, skillid)
);
Note that this third table has a foreign key to both of the other tables.
The table can also hold further information about the relationship - for example:
create table EMPLOYEE_SKILLS
( empid references EMPLOYEES
, skillid references SKILLS
, rating number
, date_certified date
, constraint EMPLOYEE_SKILLS_PK primary key (empid, skillid)
);
This is more a theory question that a programming one, but why not.
You could imagine a "many to many" as 1 table being a list of employees, and another table being a list of products sold.
Each employee is likely to "handle" more than 1 product, and each product could very well be handled by multiple employees, and it's quite possible that products A and B can be handled by, at the same time, employees C and D.
You seem to have the basic idea of one-to-one and one-to many down, in theory.
One-to-one: each item A has a separate and unique item B
In a database, you could include the new data in the same table. You could put it in a separate table, and enforce the one-to-one constraint by making the id into the remote table "unique" (indexing constraint), forcing the id for item B to not be repeated in the table. In your example, this would be a constraint added to the passportid.
One to many: each item A has some number of item Bs
In a database, you put the key in the table on the "many" side. So many Bs would have the same foreign key into table A. In your example, put an orgid as a foireign key into the employee table. Many employees can then point to a single organization, and an employee can belong to one organization.
Many to many: some number of As can be linked to any number of Bs and vice-versa
In a database, this is usually implemented as a link table, having just the IDs from both A and B. Following you example, consider that an employee can be part of multiple groups (or projects), multitasking across those groups. You could have a group table:
GROUPID (PK)
GROUPNAME
And the link table would then look like
LINKID (PK)
EMPID (FK TO EMPLOYEE)
GROUPID (FK TO GROUP)
This lets any employee be part of any number of groups, and groups to have any number of employees, AKA many-to-many.
A side comment:
Technically, you don't HAVE to have a LINKID in the link table. But it makes it easier to manage the data in that table, and is generally considered "best practice".

When will it be considered an OVERKILL when making a composite primary key?

Recently, I stumbled upon this question when looking through my database notes.
In the case of an annual examination (A Levels, O Levels) where students who did not attain their desired marks are allowed for a re-sit in the following years,
suppose there was a database designed for the school to track that has the following attributes
Student ID, Exam module, Exam Date, Exam Results
Question provided by the book (not my personal question): what would be some appropriate primary keys?[5]
Now, I know that several primary key should not be used:
Purely Student ID
(Student ID + Exam Module)
And I also know that perhaps
Artificial Primary Key - extending a 5th column that auto-increments
(Student ID + Exam Module + Exam Date)
could be used as a primary key
My question comes from making a composite primary key from all attributes (Student ID + Exam Module + Exam Date + Exam Results). A part of me thinks it will work as a composite primary key but it does not make sense to provide every single table with a composite primary key consisting of all columns.
From your description of the question, the following tuple of columns should be unique throughout the table: (StudentID, ExamModule, ExamDate), because a student may take the same exam on different dates (actually: different years). The result of the exam should not be part of this unique column tuple: this prevents a student to two results for the same exam.
Whether you decide to make this tuple of columns the primary key of your table or use some kind of serial column as primary key is mostly a matter of taste. If you go for a serial key, you need to put a composite unique constraint on the three above columns anyway.
This is not necessarily along the line of the OP's initial question:
Question: what would be some appropriate primary keys?
but..(in hind site) I would have an IDENTITY field as a primary key.
And have the StudentID as just an Index (non unique) and as an alternate Key.

The correct database schema for one-to-many relationship

I’m building a hobby site about cars. If a user clicks on a car I want to display a list of similar cars for the chosen car.
I have a main table witch stores the basic information about each car, CarDataMain, two of the columns in the table are CarID (Pk) and SimilarCarsID (Fk).
I have another table called “SimilarCars”, it has three columns; SimilarCarsID (Pk), CarGroupID and CarID.
So the SimilarCarsID-column in the SimilarCars-table has a relationship with the column SimilarCarsID in the CarDataMain-table.
Is this the correct approach, or “best practice”?
Each car can only belong to one CarGroup (CarGroupID).
Another solution would be to create a third table witch holds the relationship between CarDataMain and SimilarCars-data, but as there is a one-to-many relationship I guess this is over kill? That way I could however put the same foreign key-value in CarDataMain for all cars witch belong to the same CarGroup, witch somehow feels appealing…
A third solution would be to skip the SimilarCarsID column in CarDataMain and make the CarID a foreign key in the SimilarCars table, if you understand what I mean. But I guess there are some drawbacks with that solution…
Sorry for newbie questions (and if this question has been up before), but I want to get it right before I start :)
Ludde
Note: re-written
Design tables that describe things like Car, Group, others?
Use "join tables" to give the desired one-to-many relationships.
Tables
CarID - primary key
Group
GroupID - primary key.
Name - the name of the group.
The GroupID may not be necessary. If Name is unique then use that as the primary key.
CarGroup
CarID - foreign key to Car Table
GroupID - foreign key to Group table
This is a join table. Here you can map a given car to many groups, and map a given group to many cars.
SimilarCar
I may be misunderstanding, but is seems like you want to match cars as similar, for no particular reason. If you want to match by group, that is above; and if you want "these 2 cars are similar, period", here you go. This is not mutually exclusive to the groups.
CarID - FK to Car table
SimilarCarID - Fk to Car table
A constraint so CarId cannot match SimilarCarID -- unless you do want a car to be similar to itself. But if so then just read the car table instead.
I think your concepts need to be cleared up first. Isn't a "similar car" a car that is in the same "group"? If so, you only need 1 term. Since "group" is a reserved word it is better to use something else.
I would go with the term "category". So my Cars table would have a CategoryId column. Picture the page on the front-end where someone would add a new car, wouldn't they have a drop down list to select the Category?
So my model would be:
Cars
-Id (PK)
-Name
-CategoryId (FK to Categories)
...
Categories
-Id (PK)
-Name

SQL: can many to many relationship have a PK in addition to the FKs from the other entities

I'm having problem in inserting the values of an exam in the DB, and the reason is that every question that have been taking in the exam need to be unique which is not the case, we want the system to allow us to duplicate questions in the 60 question exam. what can I do to make this happened?
Exam (ExamID, Student.UID, ExamFB, Evaluated, ExamLevel)
Primary key (ExamID)
Foreign Key (Student.UID)
Contains (ExamID, QID, X, Y, StdAnswer, CorrectAnswer, QuestionFB)
Primary key (ExamID, QID)
Question (QID, SecID, Supervisor.UID, QBody, LawID)
Primary key (QID)
Foreign key (SecID, Supervisor.UID)
Yes, a many to many junction table does not have to be unique, although in your scenario I imagine it should be, I don't see why you would have the same question more than once on an exam, however it is quite a common scenario, to pick a slightly different scenario, imagine a service history of a car, you might have a table of mechanics, and a table of cars, and a table to store each service:
Mechanics - MechanicID (PK) Name
Cars - CarID (PK), RegistrationNumber, Make, Model
It is possible that the same mechanic will service the same car more than once, so you can't make the primary key (CarID, MechanicID), so you would either need to just assign a surrogate primary key to the service table:
Services - ServiceID (PK), CarID (FK), MechanicID(FK), ServiceDate
Or add an additional column to your table that will make the composite key unique, e.g in the above make the key (CarID, MechanicID, ServiceDate).
In your case you could have an additional column QuestionNumber (1 - 60 in your case) that identifies where the question appears in your exam, then your PK would just be (ExamID, QuestionNumber), and keep the foreign key to QuestionID.
So your database diagram would look something like one of the below:
Add an IDENTITY Attribute with the FKs together will be your PK

Database design for patients and diseases [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am creating an application (desktop) to store and retrieve patients' records along with diseases. As patients and diseases have a many to many relationship, so I've created three tables; PATIENTS, DISEASES and one is Junction table. As one patient can register more than once in a single disease over the time so 'PATIENTS' table contains composite primary key of patient's 'reference no' and 'registration date'. Table 'DISEASES' only contains 'name' as a primary key.
Now I am a little confused about the design of junction table. It is containing the composite primary key of 'PATIENTS' table and a primary key of 'DISEASES' table as foreign keys.
Should I make composite primary key of all these foreign keys in junction table or create another primary key or something different?
Any help would be greatly appreciated.
It doesn't seem like that design is quite right. If the patient's reference number uniquely identifies the patient, then that should be the primary key. If the same patient can register for a given disease multiple times, then that should be part of the key in the junction table, not in the patient table.
The primary key in the junction table should be what uniquely identifies an association, which in this case should be a composite key composed of the key from the patient table, the disease table, and the registration date.
I would suggest you one more table for cases. This table would contain an entry date. You should not use the disease name as primary key. This would make it difficult to correct typos or simply to choose a more appropriate name in the future, or maybe you would want to have a Latin as well as an English name.
Patient table
-------------
PK PatientID
Name
DateOfBirth
etc.
Disease table
-------------
PK DiseaseID
Name
Case table
-------------
PK CaseID
FK PatientID
EntryDate
etc.
CaseDisease table
-------------
PK, FK CaseID
PK, FK DiseaseID
Now you have these relations
Patient --1:n--> Case --1:n--> CaseDisease <--n:1-- Disease
EDIT:
The case table might not be necessary for now and might seem to be over-designed. However, should it turn out in future, that you have to store other data to a case as well; the db design would not have to be changed fundamentally.
UPDATE:
Alternatively, you could do it without a case table. In that case, the junction table would have a date as part of the primary key
PatientDisease table
-------------
PK, FK PatientID
PK, FK DiseaseID
PK Date
The relations would be
Patient --1:n--> PatientDisease <--n:1-- Disease
'name' as a primary key is not a good idea - there shoud be an Id column in that table which should be set as primary key
DiseasesToPatients table should be made of both foreign keys - from Patients and Diseases tables and they should be set as composite primary key on that table.