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)
)
Related
At a workplace they recycle punchcard ids (for some strange reason). So it is common to have past employees clashing with current employees. As a workaround I want to have employee punchcard id, employee name+surname as the unique primary key (fingers crossed, perhaps add date-of-birth and even passport if available). That can be accomplished with
PRIMARY KEY (pid,name,surname).
The complication is that another table now wants to reference an employee by its above primary key.
Alas, said PK has no name! How can I reference it?
I tried these but no joy:
PRIMARY KEY id (pid, name, surname),
INDEX id (pid, name, surname),
PRIMARY KEY id,
INDEX id (pid, name, surname) PRIMARY KEY,
Can you advise on how to achieve this or even how to reference a composite primary key?
Update:
The table to store employees is em.
The table which references an employee is co (a comment made by an employee).
Ideally I would use pid (punchcard id) as the unique id of each employee. But since pids are recycled, this is not unique. And so I resorted to creating a composite key or an index which will be unique and can reference that as a unique employee id. Below are the 2 tables without the composite key. For brevity, I abbreviated table names and omitted surname etc. So the question is, how can I reference an employee whose id is composite from another table co.
CREATE TABLE em (
pid INT NOT NULL,
name VARCHAR(10) NOT NULL
);
CREATE TABLE co (
id INT primary key auto_increment,
em INT,
content VARCHAR(100) NOT NULL,
constraint co2em_em_fk foreign key (em) references em(pid)
);
If another table wants to reference this one by a composite key, you don't need it to have a name - just the list of fields will do. E.g.
CREATE TABLE other_table (
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
..., -- other fields, keys etc.
FOREIGN KEY (pid, name, surname) REFERENCES employees(pid, name, surname)
);
UPD: If you expect that the set of the fields inside PK might change and you can't make a simpler PK (auto-increment integer for example) for the original table, then your best bet might be something like this:
CREATE TABLE employee_key (
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
FOREIGN KEY (pid, name, surname) REFERENCES employees(pid, name, surname)
);
-- and then reference the employees from other tables by the key from employee_key:
CREATE TABLE other_table(
ID INT AUTO_INCREMENT PRIMARY KEY,
employee_id INT NOT NULL,
... -- other fields, indexes, etc...
FOREIGN KEY (employee_id) REFERENCES employee_key(ID)
);
Then if you have a change in employee table PK, you'll only need to update employee itself and employee_key, any other tables would stay as is.
If you CAN, however, change the original employees table, I would recommend something like this:
CREATE TABLE employees(
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
... -- other fields, keys, etc.
UNIQUE KEY (pid, name, surname)
);
Then you'll have to maintain the logic of generating new pid's in your code, though, or have them in some side table.
UPD2: Regarding inserts and updates.
As for inserts: you need to insert these explicitly - otherwise how would you expect the relation to be established? If you're using an ORM library to communicate with your database, then it might provide you with the methods to specify linked objects without explicitly adding the IDs, but otherwise to insert a row into employees, employee_key and other_table you need to first INSERT INTO employees(...) ;, then get perform a separate INSERT for the employee_key (knowing the key fields you've just added to employees), get the auto-generated key from employee_key and then use that to perform inserts to any other tables.
You might simplify all this by writing an AFTER INSERT trigger for employees table (that would automatically create a row in employee_key) and/or performing your inserts via a stored procedure (that will even return back the key of the newly inserted row in employee_key). But still this work needs to be done, MySQL won't do it for you by default.
Updates are a bit easier, since you can specify ON UPDATE CASCADE when adding the foreign key - in that case a change to one of the fields in the employees will automatically trigger the same change in any tables that reference employees by this key.
You would define it
CONSTRAINT id
PRIMARY KEY (pid, name, surname)
But you should read more about how MySQL uses INDEXES and how to optimize them
https://dev.mysql.com/doc/refman/8.0/en/optimization-indexes.html
In SQL i have a table for users. On my website i want people be able to make groups consisting of 2 or more users, but i have no idea how to store that. People can be a part of multiple groups at the same time. If i'd make a table groups, how could i store it's members in that table?
You would have a table groups and one called userGroups. These would look like:
create table groups (
groupId int auto_increment primary key,
groupName varchar(255)
);
create table userGroups (
userGroupId int auto_increment primary key,
userId int not null,
groupId int not null,
foreign key (userId) references users(userId),
foreign key (groupId) references groups(groupId)
);
What you're describing is called a many-to-many relationship, and it requires a third table:
UserTable: UserID (unique), UserName, etc.
GroupTable: GroupID (unique), GroupName, etc.
UserGroups: UserGroupID (unique), UserID, GroupID
With a third table holding the primary key(pk)) of a group and a pk of a person. These columns are the pk of the table. You can have other to
Columns too, e.g. date joined or whatever. You have one row in this table per person/group.
It's a common concept/pattern so make sure you learn and understand it.
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.
I have created 3 tables in a music tracks database
Track ( id, album, genre)
Album( id, title)
Contributed ( artist, track, role)
I have chosen Id as primary keys for the first table, ( I'd, album) for the second table.
Do I need a primary key in my third table? What is my foreign key? How do I specify my foreign key?What are the unique identifiers in my third table?
I tried to populate it using tracks as foreign key( referenced to Track table, id column) but it gives me error.
Can anyone help?
For the third table, we can have two foreign keys:
Referencing to artist table (assuming we have an artist table with id and name).
Referencing to track table.
Syntax for foreign key should look like this (in create table script):
CONSTRAINT fk_contributed_track FOREIGN KEY
REFERENCS track(id)
Here is an example of a create table script with foreign key.
As far as primary key is concerned, it depends on business rules (i.e. whether one artist can have multiple roles for a track). However, for simple design, I would recommend having a numeric auto increment primary key.
I have different types of resources that can be assigned to a job. My resources, for now, are technicians and equipment. I would like to be able to store old assignments (aka, no static column in the resource tables referencing the job table).
I've been considering using a table for each resource that tracks assignments, but I would like to know if there is an ideal solution.
My tables are (for illustrative purposes):
TABLE equipment (
id,
type,
PRIMARY KEY (id)
)
TABLE technicians (
id,
name,
level,
PRIMARY KEY (id)
)
TABLE jobs (
jobno,
starts,
ends
PRIMARY KEY (jobno)
)
TABLE table equipment_assignments (
id,
jobno,
PRIMARY KEY (id, jobno),
FORIEGN KEY (id) REFERENCES equipment(id),
FORIEGN KEY (jobno) REFERENCES jobs(jobno)
)
TABLE table technician_assignments (
id,
jobno,
PRIMARY KEY (id, jobno),
FORIEGN KEY (id) REFERENCES technicians(id),
FORIEGN KEY (jobno) REFERENCES jobs(jobno)
)
Another way of doing this is to introduce a resource table that equipment and technician reference, or that contains a NULLable reference to equipment and technician. You then have resource assignments rather than entity specific assignments, I would argue that the former of these approaches makes it easier to introduce new resource types.