what is the correct design for ER mapping for this situation? - sql

I need to model this problem :
One faculty may supervise several students or not. One student has at
least one, at most two supervisors.
I'm looking for actual Relational table design on how to do this.

The easiest (somewhat bold) way to model this is
a STUDENT table
a FACULTY table
Now give STUDENT columns FACULTY1 and FACULTY2. Both are foreign keys to FACULTY. Constrain FACULTY1 with NOT_NULL. This enforces that a student has at least one FACULTY. FACULTY2 can be null, but it still a foreign key.
FACULTY somehow does not know anything about STUDENT. When no STUDENT references a FACULTY it has no students and any number of Students can reference faculty.
This model has a number of drawbacks (I said it is bold):
A STUDENT being supervised by only one FACULTY must have this set in FACULTY1 (not FACULTY2). Likewise when a student who was supervised by 2 FACULTIES deletes one of them, you can only delete FACULTY2 or you must first swap the fields. You can circumvent this by a more clever constraint (FACULTY1 is not null or FFACULTY2 is not null)
If you ever want to change the design, so a STUDENT can have 3 FACULTIES you need to add columns to STUDENT. This however, is not as bad as it may sound.
On the pro side, there is nothing but referential integrity and NOT NULL involved in this design.

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".

SQL relationship between student, lessons and attendance

For a school project I'm trying to store students, their attendance and which online lessons they are allowed to view.
For example a yellow belt student is allowed to watch white and yellow belt lessons. The belt system is replaced by a kyu, which can also have a dan.
So far I've created the following:
Student: studentID (PK), firstname, lastname, age, kyu, dan
Attendance: attendanceID (PK), studentID (FK), date
Lesson: lessonID(PK), name, kyu, dan
I'm stuck at finding a possible relationship between lesson and student, since it feels wrong to just put a FK to lesson in student.
As far as I'm aware, it's just one big class, so I can't form a relationship between student-class and class-lesson.
I understand that you have a N-M relationship between lessons and students, where each student can enroll in several lessons, and each lesson may be (and hopefully is) taken by many students.
The typical way to represent such relationship is to create a bridge table, that stores which student participates which lesson. Say table student_lesson :
id : primary key
lessonID : foreign key towards table lesson
studentID : foreign key towards table student
You would need to create a unique constraint on columns (lessonID, studentID) - or drop skip id, and make (lessonID, studentID) the primary key of the bridge table.
As far as I understood, it should be many to many relationship, as many students can go to the same lesson, and student can have many leasons, so another table holding student and leason id will solve the problem, I think

ER Diagram Participation Constraints in SQL

I'm trying to understand converting ER diagrams into SQL CREATE statements, but I am having a hard time with understanding how participation constraints work. In an ER diagram a participation constrain is represented by a bold line which means that every tuple in the table must appear in the relationship table. If there is a participation constraint and a key constraint (total) it is possible to fulfil the key constrain.
Is there ever a situation in which there is a way to enforce a participation constraint that isn't also a key constraint without using assertions or check constraints?
Edit
I was more confused about the whole concept as opposed to one particular example, but I was able to find an example that I drew out the diagram for that would illustrate my confusion. In the picture below we have a participation constraint and a key constraint from professors to teachers; therefore every professor must teach 1 class and only 1 class. This constraint can be enforced by having a professors_teach table as opposed to having two separate tables; by making the professors ssn the primary key there will only ever be 1 entry for each professor in the professors_teach table, and since it will have all the records that normally would be put in the professors table then every professor must be in the new table.
My confusion is in the participation constraint from course to teacher; basically what the diagram is saying is that every course must have at least one teacher; which I don't think can be enforced without using assertions or check constraints.
For this case you dont need a relatioship.
You only need table teacher, and define the field course_id (unique). In this case you have teachers and they can have 0 or 1 course. And each course will be teach for only one teacher.
teacher_id (primary key)
teacher_name
ssn
course_id (unique) fk reference courses(course_id)
Courses
course_id (primary key)
course_name
But you shouldnt enforce every course have teacher in the db because a new course will need a teacher right away. Is better you insert the course and then assign a teacher.
You merge the relation Teaches and the Entity Professor in:
CREATE TABLE Prof_teaches(
ssn INTEGER,
semesterid INTEGER,
courseID INTEGER NOT NULL,
FOREIGN KEY courseID REFERENCES Course (courseid),
PRIMARY KEY ssn
)
CREATE TABLE Course(
courseid INTEGER PRIMARY KEY
)
This is for total participation and key constraint as defined in the Book by Ramakrishnan. Meaning that each Professor (note, single f), participates in al least (total participation) and at most (key constraint) one teaches relationship.

A One To Many relationship model where the data on the right side can be quite variable?

Here is the problem I'm trying to solve:
Entity A : a_id
Entity B : b_id
One A can use Many B's. However, not all Bs are used by all As.
Here is the best example I can think of :
One teacher has many students.
Some students are taught by more than one teacher.
What is a relationship so I can add/remove students being taught by one teacher, but not affect the teachers already teaching said students?
you need a third table known as mapping between this two tables.create this table so:
Table Student_Teacher_Mapping
Id (Int)
TeacherId(Int) // foreign key for teacher table
StudentId(Int) // foreign key for student table
i think this is what you want.
You need a StudentTeacher entity that will relate the two together. It would have an a_id column and a b_id column.

Constraints instead Triggers (Specific question)

I read here some reasons to use constraints instead of triggers. But I have a doubt. How can be assure (using only constraints), the coherence between SUPERCLASS tables and SUBCLASSES tables?
Whit a trigger is only a matter of check when INS.. UPD...
Is there a way to define that kinda relation by using only constraints (I'm newbie at this), thanks!
You can use constraints to ensure that every ContractEmployees row has a corresponding Employees row, and likewise for SalariedExployees. I don't know of a way to use constraints to enforce the opposite: making sure that for every Employees row, there is a row either in ContractEmployees or SalariedEmployees.
Backing up a bit... there are three main ways to model OO inheritance in a relational DB. The terminology is from Martin Fowler's Patterns of Enterprise Application Architecture:
Single table inheritance: everything is just in one big table, with lots of optional columns that apply only to certain subclasses. Easy to do but not very elegant.
Concrete table inheritance: one table for each concrete type. So if all employees are either salaried or contract, you'd have two tables: SalariedEmployees and ContractEmployees. I don't like this approach either, since it makes it harder to query all employees regardless of type.
Class table inheritance: one table for the base class and one per subclass. So three tables: Employees, SalariedEmployeees, and ContractEmployees.
Here is an example of class table inheritance with constraints (code for MS SQL Server):
CREATE TABLE Employees
(
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
FirstName VARCHAR(100) NOT NULL DEFAULT '',
LastName VARCHAR(100) NOT NULL DEFAULT ''
);
CREATE TABLE SalariedEmployees
(
ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
Salary DECIMAL(12,2) NOT NULL
);
CREATE TABLE ContractEmployees
(
ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
HourlyRate DECIMAL(12,2) NOT NULL
);
The "REFERENCES Employees(ID)" part on the two subclass tables defines a foreign key constraint. This ensures that there must be a row in Employees for every row in SalariedEmployees or ContractEmployees.
The ID column is what links everything together. In the subclass tables, the ID is both a primary key for that table, and a foreign key pointing at the base class table.
Here's how I'd model a contract vs salary employee setup:
EMPLOYEE_TYPE_CODE table
EMPLOYEE_TYPE_CODE, pk
DESCRIPTION
Examples:
EMPLOYEE_TYPE_CODE DESCRIPTION
-----------------------------------
CONTRACT Contractor
SALARY Salaried
WAGE_SLAVE I can't be fired - slaves are sold
EMPLOYEES table
EMPLOYEE_ID, pk
EMPLOYEE_TYPE_CODE, foreign key to the EMPLOYEE_TYPE_CODE table
firstname, lastname, etc..
If you're wanting to store a hierarchical relationship, say between employee and manager (who by definition is also an employee):
EMPLOYEES table
EMPLOYEE_ID, pk
EMPLOYEE_TYPE_CODE, foreign key to the EMPLOYEE_TYPE_CODE table
MANAGER_ID
The MANAGER_ID would be filled with the employee_id of the employee who is their manager. This setup assumes that an employee could only have one manager. If you worked in a place like what you see in the movie "Office Space", you need a different setup to allow for an employee record to associate with 2+ managers:
MANAGE_EMPLOYEES_XREF table
MANAGER_EMPLOYEE_ID, pk, fk to EMPLOYEES table
EMPLOYEE_ID, pk, fk to EMPLOYEES table
Databases are relational and constraints enforce relational dependencies pretty well, been doing so for some 30 years now. What is this super and sub class you talk about?
Update
Introducing the OO inheritance relationships in databases is actually quite problematic. To take your example, contract-employee and fulltime-employee. You can model this as 1) a single table with a discriminator field, as 2) two unrelated tables, or as 3) three tables (one with the common parts, one with contract specific info, one with fulltime specific info).
However if you approach the very same problem from a traditional normal form point of view, you may end up with a structure similar to 1) or 3), but never as 2). More often than not, you'll end up with something that looks like nothing you'd recommend from your OO design board.
The problem is that when this collision of requirements happens, today almost invariably the OO design will prevail. Often times, the relational model will not even be be on the table. Why I see this as a 'problem' is that most times databases far outlive their original application. All too often I see some design that can be traced back to a OO domain driven design session from an application long forgotten, and one can see in the database schema the places where, over time, the OO design was 'hammered' into place to fit what the relational engine underneath could support, scale and deliver. The tell sign for me is tables organized on a clustered index around a identity ID when no one ever is interrogating those tables for a specific ID.