Self-referential relationship table design: one or two tables? - mysql

CREATE TABLE Employee
(
id INT,
boss INT REFERENCES Employee(id),
PRIMARY KEY (id)
);
One employee can have many bosses and one boss can have many employees.
Does this table function the same as this two-table design?
CREATE TABLE Employee
(
id INT,
PRIMARY KEY (id)
);
Create table ManagerRelation (
id_from int NOT NULL,
id_to int NOT NULL,
PRIMARY KEY (id_from, id_to),
FOREIGN KEY (id_from) REFERENCES Employee(id),
FOREIGN KEY (id_to) REFERENCES Employee(id)
);
The second table ManagerRelation stores ids of workers who have boss-employee relationship.
My question is, are these two design right? If right, are they exactly the same functionally?

The two designs are quite different. The first requires that each employee have (at most) one boss, although each boss could have many employees.
The second allows for employees to have more than one boss.
From your description of the problem, the second form is the more appropriate data model. From my understanding of boss-employee relationships, I would expect the first to be correct.

Related

How to implement a restriction to create AT MOST one null value in a column

I'm trying to implement a sort of tree in the table employee, where each employee except for one has a supervisor, who is another employee in the same table. The one with a NULL value in their supervisor slot would be the "manager" or something. Is there a way to implement it? I know in other languages this would be trivial with a partial index, but Mysql doesn't support those, so I'm at a loss.
Here's the table declaration I made without this restriction, and for the record, employee is meant to be one of four specializations of the person table, with further specialization into either associates or partners:
create table employee
(
ID numeric(7,0),
supervisor_ID numeric(7,0),
postition enum('associate','partner') NOT NULL,
primary key (ID),
foreign key (ID) references person(ID),
foreign key (supervisor_ID) references employee(ID)
);

Best approach to store 100+ columns in one table in MySQL

I am working on a data model where I need to store Employee's basic details and his rating of skillsets in MySQL database.
The number of skillsets for each employee is more than 100.
So the information I need to store is as following:
Employee ID, Name , Department , Contact info, Skillset1,Skillset2,Skillset3, ... , Skillset115
Is creating one table with approximately 120 columns is good approach?
If not, what is the best practice to deal with this kind of requirement.
No. You should have a separate table with one row per employee and per skill:
create table employeeSkills (
employeeSkillId int auto_increment primary key,
employeeId int not null,
skill varchar(255),
constraint fk_employeeSkills_employeeid foreign key (employeeId) references employees(employeeId)
);
In fact, you should really have two extra tables. The skills themselves should be stored in a separate table and the above should really be:
create table employeeSkills (
employeeSkillId int auto_increment primary key,
employeeId int not null,
skillId int,
constraint fk_employeeSkills_employeeid foreign key (employeeId) references employees(employeeId),
constraint fk_employeeSkills_skillid foreign key (skillId) references skills(skillId)
);
This type of table is called a "junction table", and is common in any properly constructed data model.
You need to create two tables that would handle the skills and the assigned skill for each employee.
This would give you a proper order in your database and also will extend your options in the future. It'll be better in search, add and assign skills to each employee. It's even more organized and would be able to be expanded easily such as adding skills category and sub-category.
The two tables schema should be something like this :
CREATE TABLE Skills (
Skill_ID INT NOT NULL AUTO_INCREMENT,
Skill_Description VARCHAR(250),
PRIMARY KEY (`Skill_ID`)
);
CREATE TABLE EmpolyeeSkills (
ES_ID INT NOT NULL AUTO_INCREMENT,
Skill_ID INT,
Employee_ID INT,
PRIMARY KEY (`ES_ID`),
CONSTRAINT FK_EMPLOYEEID FOREIGN KEY (Employee_ID) REFERENCES Employees(Employee_ID),
CONSTRAINT FK_SKILLID FOREIGN KEY (Skill_ID) REFERENCES Skills(Skill_ID)
);
The Skills table will assign an ID for each skill, and it'll be in a separate table. This will make you have a unique skills list, there won't be any redundancy. Then, you'll use EmployeeSkills to save the assigned skills on each Employee_ID. Which you can use it later on to join it with other records.
The FOREIGN KEY on Employee_ID and Skill_ID will help you in monitoring the skills between them.
The ES_ID primary key for EmpolyeeSkills will be an additional advantage that can be helpful in the future. For instance, if you want to know the latest skill that has been assigned, then your faster approach will be getting the last ES_ID as it's an AUTO_INCREMENT. This is just one advantage from tons of others.

Role of foreign key in bidirectional relationships

I am a little confused about designing the database for a bidirectional relationship between a customer & product.
Just to be clear a bidirectional relationship ensures that a customer is aware of his products & a product is aware of it's customer.
I have a Customer table & a Product table. Product table has a foreign key of Customer table.
To create a bidirectional relationship should a Customer table also contain a foreign key of Product table? I've seen ORM examples where just one FK reference is OK for a bidirectional relationship but still a little confused, can anyone enlighten me on this?
What difference would it make if I put a FK of Product table in the Customer table?
I think you just want a CustomerProducts table, to represent the relationship:
create table CustomerProducts (
CustomerProductId int not null auto_increment primary key,
CustomerId int not null,
ProductId int not null,
Amount int not null,
. . .
foreign key (CustomerId) references Customers(CustomerId),
foreign key (ProductId) references Products(ProductId)
);
This is called a "junction" table. It can have additional columns (such as Amount) specifying characteristics of the relationship.

parent child table sql issue

i have 3 tables below which have many to many relation...In student table i have multiple foreign keys sec_id,ad_id but i dont know how to add foreign key as parent-child relation please help me out..
CREATE TABLE student(
s_id int AUTO_INCREMENT,
name varchar(30) NOT NULL,
PRIMARY KEY(s_id)
)
CREATE TABLE section(
sec_id int AUTO_INCREMENT,
name varchar(2) NOT NULL,
PRIMARY KEY(sec_id)
)
CREATE TABLE advisor(
ad_id int AUTO_INCREMENT,
name varchar(2) NOT NULL,
PRIMARY KEY(ad_id)
)
If a student can have at most one advisor, then it's a one-to-many relationship.
The normal pattern for implementing that relationship is to define a foreign key column in the child table, the table on the "many" side of the relationship. For example:
ALTER TABLE student ADD ad_id INT COMMENT 'fk ref advisor';
Further, some storage engines, like InnoDB, support and enforce foreign keys. That is, we can have the database enforce restrictions (constraints) on values that can be stored in columns defined as foreign keys.
For example, we can establish a rule that says that a value stored in the ad_id column in the student table... must be found in a row in the advisor table, in the ad_id column.
For example:
ALTER TABLE student ADD CONSTRAINT fk_student_advisor
FOREIGN KEY (ad_id) REFERENCES advisor(ad_id)
ON DELETE RESTRICT ON UPDATE CASCADE
This also enforces a rule that a row from advisor table cannot be deleted if there are rows in student table that reference it.
That same pattern can be repeated for any one to-to-many relationship. For example, if a student can be related to at most one section we can add a foreign key in the same way.
If there's a many-to-many relationship, then we introduce a relationship table that has foreign keys referencing the two related entity tables.
If a student can be related to zero, one or more section, and a section can be related to zero, one or more student, that's an example of a many-to-many relationship.
We can introduce a new table like this (as an example):
CREATE TABLE student_section
( student_id INT NOT NULL COMMENT 'pk, fk ref student'
, section_id INT NOT NULL COMMENT 'pk, fk ref section'
, PRIMARY KEY (student_id, section_id)
, CONSTRAINT fk_student_section_student
FOREIGN KEY student_id REFERENCES student(s_id)
ON DELETE CASCADE ON UPDATE CASCADE
, CONSTRAINT fk_student_section_section
FOREIGN KEY section_id REFERENCES section(sec_id)
ON DELETE CASCADE ON UPDATE CASCADE
)
With that in place, to establish a relationship between a student and a section, we insert a row to the new student_section table. If the student is related to another section, we add another row to the table, referencing the same student, but a different section.
The value stored in the student_id column refers to a row in the student table; and a value stored in the section_id column refers to a row in the section table.
(The many-to-many relationship is really composed of rows in a new table that has a one-to-many relationship to two other tables.)

How to create a table that uses a whole other foreign table?

Let's say I have this:
CREATE TABLE `classes`
(
`class_ID` INT AUTO_INCREMENT,
FOREIGN KEY (`student_ID`) references `students`(`student_ID`),
PRIMARY KEY (`class_ID`)
)
ENGINE = InnoDB;
The thing here is that each class refers to a single student. But I want it to refer to a whole other table of students, for example:
CREATE TABLE `students`
(
`student_ID` INT AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`student_ID`)
)
ENGINE = InnoDB;
Hence, I want multiple student tables, which each table associated to a class. How can I do this? Do i have to declare a single table (e.g. students1, students2, etc.) for each class?
Thanks!
The answer to this will be a little difficult to understand at first. After a while it becomes natural. Is is a well-known design pattern. You need a third table:
create table students_in_courses(studentid, courseid)
In this table you have a row for each student and each course that student is in. You can turn this sentence around: A row for each course and each student that is in this course.
It is a "link table". It is used for M:N mappings.
You can think of this table as an entity, just like students and courses. You could even add additional columns:
create table students_in_courses(studentid, courseid, date_entered, date_exited, grade)
A constant number of tables is enough.
Let me try a different explanation: We could store the information which student is in which course by saving a matrix with the students as its rows and the courses as its columns. Every cell has a bool: student is in this course yes/no.
Now we save this entire matrix in a table like this:
create table students_in_courses(studentid, courseid, is_in_course bit) primary key(studentid, courseid)
For each cell a row. Now we delete all rows with is_in_course = 0 and drop that column because it only contains 1's now. We are back at the original solution. Our "link-table" stores the non-zero cells of the cross-product matrix of the two tables.
No. you create a single table that has foreign keys referencing both tables:
CREATE TABLE students_classes (
student_id int,
classes_id int,
PRIMARY KEY (student_id, classes_id),
FOREIGN KEY (student_id) REFERENCES students (student_ID),
FOREIGN KEY (classes_id) REFERENCES classes (class_ID)
);
That way you can have student (example) #7 in classes (#53 and 37 and 83), student #12 in classes (#53, #212, #7), etc... without conflict.