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.
Related
I'm planning on creating an "Organizations" table, where the columns are:
Organization Id (primary key), Name, Plan and Company Id (foreign key).
My issue is that per organization there can be multiple companies, that means, I would need to have multiple records with the same Organization Id but with a different Company Id, but since the Organization Id is my primary key I know I can't do this (because it's unique).
How can I structure/design this? It's essentially a one to many relationship between an organization and a company. I'm just starting out with MySQL so I may be missing something obvious.
Drop companyId from the organisations table and have organisationId as foreign key in the companies table.
CREATE TABLE Organizations (
OrganizationId INTEGER,
... other fields,
PRIMARY KEY (OrganizationId)
)
CREATE TABLE Companies (
CompanyId INTEGER,
OrganisationId INTEGER,
... other fields,
PRIMARY KEY (CompanyId),
FOREIGN KEY (OrganisationId) REFERENCES Organizations(OrganisationId)
)
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.
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.
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.)
In MySQL, how do you combine 2 foreign keys in a table to become a primary key?
I have two tables, one Staff, one Roles, each containing their own primary keys, StaffID and RoleID. I have created a third table called StaffRole which will contain the StaffID and RoleID, keeping in mind this is a one to many relationship, as a staff member may have 1 or more roles.
How would you combine the foreign key of StaffID and RoleID to create a new unique primary keys for the table StaffRole.
Technically, what you are describing is not a one-to-many relationship, but instead it is a many-to-many relationship since one Staff record relates to many Role records, but one Role record also relates to many different Staff. Your use of the join table StaffRole is the typical way of handling the relationship.
This is semantics, but it isn't really a matter of combining the two foreign keys, so much as just creating a third key which is the composite of the two and also the primary key. So your table will have two FOREIGN KEY definitions, one each for the two columns, and one composite PRIMARY KEY definition across both of the columns.
CREATE TABLE StaffRole (
StaffID INT NOT NULL,
RoleID INT NOT NULL,
/* Composite primary key on both columns */
PRIMARY KEY (StaffID, RoleID),
/* Two separate foreign keys */
FOREIGN KEY (StaffID) REFERENCES Staff (StaffID),
FOREIGN KEY (RoleID) REFERENCES Roles (RoleID)
) ENGINE=InnoDB;
Note, I have specified InnoDB as the table type, since MySQL will not enforce the FOREIGN KEYs on MyISAM tables.
You can create a StaffRoleID as a primary key, and use StaffID and RoleID as foreign keys.