Reputation: 11
So i'm trying to make a database based off a spec sheet (was given an ER diagram and a DB Schema) and said sheet specifies that the first two table contain references to each other, like so:
WAREHOUSE
Column name Data type Comments
warehouseID VARCHAR(3) Primary key
street VARCHAR(20)
city VARCHAR(15)
state VARCHAR(3) Examples – VIC, NSW, QLD
postcode VARCHAR(4) Examples – 3350, 2001, 3001
managerID INT FK–References EMPLOYEE.StaffID
EMPLOYEE
Column name Data type Comments
staffID INT A_I Primary key
surname VARCHAR(20)
firstName VARCHAR(15)
dob Date Short date– Example 06/09/1982
street VARCHAR(20)
city VARCHAR(15)
state VARCHAR(3) Examples – VIC, NSW, QLD, TAS
postcode VARCHAR(4) Examples – 3350, 3355, 2001, 3001
salary Decimal(19,4)
warehouseID VARCHAR(3) FK – References WAREHOUSE. warehouseID
supervisedBy INT FK – References EMPLOYEE.StaffID
My MySQL creation code is as follows *I added the last column to "Warehouse" after table creation because i was unable creat ehm one after the other due to the FK's contained in both:
CREATE DATABASE IF NOT EXISTS WareMart_30114465;
USE WareMart_30114465;
CREATE TABLE IF NOT EXISTS Warehouse
(
warehouseID VARCHAR(3) NOT NULL,
street VARCHAR(20),
city VARCHAR(15),
statesh VARCHAR(3),
postcode VARCHAR(4),
PRIMARY KEY (warehouseID)
);
CREATE DATABASE IF NOT EXISTS WareMart_30114465;
USE WareMart_30114465;
CREATE TABLE Employee
(
staffID INT NOT NULL AUTO_INCREMENT,
surname VARCHAR(20),
firstName VARCHAR(15),
dob date,
street VARCHAR(20),
city VARCHAR(15),
statesh VARCHAR(3),
postcode VARCHAR(4),
salary DECIMAL(19,4),
warehouseID VARCHAR(3),
PRIMARY KEY (staffID),
FOREIGN KEY (warehouseID) REFERENCES Warehouse(warehouseID)
);
CREATE DATABASE IF NOT EXISTS WareMart_30114465;
USE WareMart_30114465;
ALTER TABLE Warehouse ADD managerID INT NOT NULL;
ALTER TABLE Warehouse ADD CONSTRAINT managerID
FOREIGN KEY (managerID) REFERENCES Employee(staffID)
ON UPDATE CASCADE
ON DELETE CASCADE;
Of course with the FK's being set up the way they are (and have to be unless atm i can do it somehow else), i cant seems to inert anything with out getting an error. Current Insert code as follows:
USE WareMart_30114465;
INSERT INTO Warehouse (warehouseID, street, city, statesh, postcode)
VALUES ('W01', 'SturtSt', 'Ballarat', 'VIC', '3350' );
INSERT INTO Employee (staffID, surname, firstName, dob, street, city, statesh, postcode, salary, warehouseID)
VALUES (1, 'Smith', 'John', 01/02/03, 'Example St', 'GenericPlace', 'ABC', '1234',
Personally am at a loss as to why i have to set up a circle/Chicken-Egg reference, as i thought that was against conventions.
Any thoughts?
Upvotes: 1
Views: 1934
Reputation: 8823
The conventional way to solve the "chicken and egg" dilemma on inserting records into tables with mutual FOREIGN KEY
dependencies is to allow NULL
for a foreign key constrained column in one of the two tables.
For example, instead of NOT NULL
on the managerID
of the WAREHOUSE
table, you would define the table to allow Nulls in this field. Then the WAREHOUSE
records could be INSERT
ed before the EMPLOYEE
records that correspond to the managerID
you want to assign, temporarily putting a null value there. Subsequently the WAREHOUSE
record can be updated with a correct managerID
.
This is generally considered better than turning off the checking of foreign keys entirely because that is a "global" setting, and you don't want to assume your task is the only one running.
Upvotes: 0
Reputation: 1490
I do not know if it is against your specs and if they are fixed. But personally I would add another table with different employee positions. e.g 1 = Manager, 2= Standard Employee, etc...
Then add a field in the Employee table called position or something relevant.
Then the relationship would be singular between the warehouse and employee table and then when searching in the query you would select employee where warehouseId matches and position field is manager.
Sorry for no working example. An example is like:
Select secUser.* from secUser JOIN secUserRole ON secUser.pkUser = secUserRole.fkUser WHERE fkRole = 0
In which the above gets all user details where the UserRole table's Role value = 0
Warehouse
WarehouseID
etc.
Employee
EmployeeID
PositionID
etc.
Position
PositionID
Name
etc.
Upvotes: 1
Reputation:
The problem will only occur when inserting a warehouse, and since inserting a warehouse is likely to be a rare occurrence you can turn off the foreign key checks while you do it with:
SET foreign_key_checks = 0;
and enable it when you're done with
SET foreign_key_checks = 1;
The MySQL reference is here
Upvotes: 0