MySQL - complete newbie - what's wrong with my foreign key coding? - mysql

When trying to create the foreign keys on the last table I get the error "cannot add foreign key constraint" -
create database library_PW;
use library_PW;
create table title(
title_id varchar(20)primary key,
name varchar(50)not null,
reservation_no numeric(10),
lending_time varchar(15));
create table item(
title_id varchar(20)not null,
item_id varchar(20)not null,
constraint pk_item primary key(title_id,item_id));
create table magazine(
mag_id varchar(20)not null,
mag_date varchar(15)not null,
constraint pk_magazine primary key(mag_id,mag_date));
create table book(
ISBN varchar(20)primary key,
date_added date not null);
create table author(
author_id varchar(20)primary key,
author_name varchar(30)not null);
create table book_author(
ISBN varchar(20),
author_id varchar(20),
index (ISBN),
index (author_id),
constraint pk_book_author primary key(ISBN,author_id),
constraint fk_ISBNCode foreign key (ISBN) references book(ISBN),
constraint fk_authorcode foreign key (author_id) references author(author_id));
create table borrower(
membership_id varchar(20)primary key,
name varchar(20)not null,
address varchar(60)not null,
dob date not null,
date_joined date not null,
telephone numeric(12),
email varchar(30));
create table reservation(
title_id varchar(20),
membership_id varchar(20),
reserve_date varchar(20),
index (title_id),
index (membership_id),
constraint pk_reservation primary key(title_id, membership_id,reserve_date),
constraint fk_title foreign key(title_id) references title(title_id),
constraint fk_mem_id foreign key(membership_id) references borrower(membership_id));
create table loan(
title_id varchar(20),
item_id varchar(20),
borrower_date varchar(20),
index (title_id),
index (item_id),
constraint pk_reservation primary key(title_id,item_id,borrower_date),
constraint fk_loantitle foreign key(title_id) references title(title_id),
constraint fk_loanitem foreign key(item_id) references item(item_id));
Thanks in advance!

When I run into this issue, its always because I choose the wrong type data type.. The data type for the child column must match the parent column exactly.
Example: table.key = int & table.child=vchar
For me, its always that! Hope that helps.

Thanks all! It wasn't the data type (for once), it was the problem with the table item as suggested, and SHOW ENGINE INNODB STATUS\G pointed me to the answer.
All that was wrong was in the table item I should have had item_id before title_id.
Thanks again.

Related

Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'projects_ibfk_1' in the referenced table 'employees'

CREATE DATABASE employeeDB;
USE employeeDB;
CREATE TABLE employees(
employeeid NUMERIC(9),
firstname VARCHAR(10),
lastname VARCHAR(20),
deptCode CHAR(5),
salary NUMERIC(9, 2),
PRIMARY KEY (employeeid)
);
CREATE TABLE projects(
projectid CHAR(8),
deptcode CHAR(5),
description VARCHAR(200),
startdate DATE,
stopdate DATE,
revenue NUMERIC(12, 2),
PRIMARY KEY (projectid),
FOREIGN KEY (deptcode) REFERENCES employees(deptCode)
);
CREATE TABLE departments(
code CHAR(5),
name VARCHAR(5),
managerid NUMERIC(9),
subdeptof CHAR(5),
PRIMARY KEY (code),
FOREIGN KEY (managerid) REFERENCES employees(employeeid),
FOREIGN KEY (subdeptof) REFERENCES projects(deptcode)
);
ALTER TABLE employees ADD FOREIGN KEY (deptCode) REFERENCES projects(deptcode);
Something wrong at the line CREATE TABLE projects(...). When I run the code in MySQL it give the Error Code 1822. What is the problem ? Any expert can help ?
You cant create foreign key with a non-primary key, and if you really want to create foreign key to non-primary key (column), the column must be indexed with a unique constraint on it.
So either create unique constraint on deptCode column, or reference by already existing primary key, or change the primary key.

Error Code 3078 - Foreign Key not compatible - what does this even mean?

I keep getting this Error code:
Alter Table PAYMENT add FOREIGN KEY (CustomerId)REFERENCES CUSTOMER(CustomerId) Error Code: 3780. Referencing column 'CustomerId' and referenced column 'CustomerId' in foreign key constraint 'payment_ibfk_7' are incompatible. 0.0010 sec
I don't know how to fix it. Please Help.
Create Schema IF NOT EXISTS AUTOMOBILE_COMPANY;
USE AUTOMOBILE_COMPANY;
CREATE TABLE IF NOT EXISTS CUSTOMER(
CustomerId INT NOT NULL PRIMARY KEY,
CustomerFname VARCHAR(30) NOT NULL,
CustomerLname VARCHAR(30) NOT NULL,
CustomerPhone VARCHAR(15) NOT NULL UNIQUE,
CustomerGender VARCHAR(10),
CustomerYearly_salary VARCHAR(15),
CustomerStreet VARCHAR (30),
CustomerCity VARCHAR (30),
CustomerState VARCHAR(30),
CustomerPostcode VARCHAR(6),
ProductId INT NOT NULL,
PaymentId INT
);
CREATE TABLE IF NOT EXISTS DEALERS(
DealerName VARCHAR (10)NOT NULL PRIMARY KEY,
DealerBrand VARCHAR (7),
DealerModel VARCHAR (4),
DealerColour VARCHAR (5),
DealerAvailability VARCHAR (12),
DealerSalesByDate Date,
DealerCarEngine VARCHAR (17),
DealerTransmission VARCHAR (16),
DealerBodyStyle VARCHAR (20)
);
CREATE TABLE IF NOT EXISTS EMPLOYEE(
EmployeeSsn INT NOT NULL PRIMARY KEY,
EmployeeFirst_name VARCHAR(20) NOT NULL,
EmployeeLast_name VARCHAR(20) NOT NULL,
EmployeeBirthday INT NOT NULL,
EmployeeStreet VARCHAR (30),
EmployeeCity VARCHAR (30),
EmployeePostcode VARCHAR(6),
EmployeeState VARCHAR(30),
EmployeeSalary DECIMAL(6) NOT NULL,
EmplyeeSex VARCHAR(6)
);
CREATE TABLE IF NOT EXISTS PAYMENT(
PaymentId INT PRIMARY KEY,
Bank VARCHAR (30) NOT NULL,
CustomerId INT,
EmployeeSsn INT ,
Amount DECIMAL(7)NOT NULL,
PaymentDate DATETIME NOT NULL,
ProductId INT NOT NULL
);
CREATE TABLE IF NOT EXISTS PRODUCT(
ProductId INT NOT NULL PRIMARY KEY,
ArticleNumber VARCHAR (30)NOT NULL,
brand VARCHAR (7),
model VARCHAR (4),
colour VARCHAR (5),
availability VARCHAR (12),
CustomerId INT NOT NULL,
StoreId INT NOT NULL,
CarEngine VARCHAR (17),
Transmission VARCHAR (16),
BodyStyle VARCHAR (20)
);
ALTER TABLE CUSTOMER ADD FOREIGN KEY (productid) REFERENCES PRODUCT(productid);
ALTER TABLE CUSTOMER ADD FOREIGN KEY (paymentid) REFERENCES PAYMENT(paymentid);
CREATE TABLE IF NOT EXISTS RENTAL(
RentalId INT NOT NULL PRIMARY KEY,
RentalDate DATETIME NOT NULL,
ReturnDate DATETIME NOT NULL,
CustomerId INT NOT NULL,
EmployeeSsn INT NOT NULL
);
CREATE TABLE IF NOT EXISTS MANUFACTURER(
StoreId INT NOT NULL PRIMARY KEY,
Street VARCHAR (30)NOT NULL,
City VARCHAR (30)NOT NULL,
State VARCHAR(30)NOT NULL,
Postcode VARCHAR(6)NOT NULL,
ArticleNumber VARCHAR (30)NOT NULL,
SupplierParts VARCHAR (20) NOT NULL
);
CREATE TABLE IF NOT EXISTS STORE (
StoreId INT NOT NULL PRIMARY KEY,
StoreStreet VARCHAR (30)NOT NULL,
StoreCity VARCHAR (30)NOT NULL,
StoreState VARCHAR(30)NOT NULL,
StorePostcode VARCHAR(6)NOT NULL,
StoreManager_staff VARCHAR(30)
);
CREATE TABLE IF NOT EXISTS SUPPLIER(
SupplierParts VARCHAR (20) NOT NULL PRIMARY KEY,
SupplierArticle_number INT NOT NULL
);
Alter Table PAYMENT add FOREIGN KEY (ProductId) REFERENCES PRODUCT(ProductId);
Alter Table PAYMENT add FOREIGN KEY (CustomerId)REFERENCES CUSTOMER(CustomerId);
Alter Table PAYMENT add FOREIGN KEY (EmployeeSsn)REFERENCES EMPLOYEE(EmployeeSsn);
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmplyeeSsn);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
ALTER TABLE SUPPLIERS ADD FOREIGN KEY (SupplierParts)REFERENCES MANUFACTURER(SupplierParts);
ALTER TABLE STORE ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn) ;
ALTER TABLE STORE ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
ALTER TABLE PRODUCT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
ALTER TABLE PRODUCT ADD FOREIGN KEY (StoreId) REFERENCES MANUFACTURER (StoreId);
ALTER TABLE RENTAL ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (SupplierParts)REFERENCES SUPPLIER(SupplierParts);
The code you have posted has a few typo's/errors:
-- references "EmplyeeSsn" instead of "EmployeeSsn"
ALTER TABLE RENTAL ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmplyeeSsn);
-- ArticleNumber is not defined as unique in PRODUCT, can be resolved by adding a unique
-- constraint to PRODUCT on the column ArticleNumber
ALTER TABLE MANUFACTURER ADD FOREIGN KEY (ArticleNumber)REFERENCES PRODUCT(ArticleNumber);
-- Supplier parts is not unique in MANUFACTURER, it is the primary key of SUPPLIERS though
-- So this may be the wrong way round
ALTER TABLE SUPPLIERS ADD FOREIGN KEY (SupplierParts)REFERENCES MANUFACTURER(SupplierParts);
-- STORE contains neither a column called "EmployeeSsn" or "SupplierParts"
ALTER TABLE STORE ADD FOREIGN KEY (EmployeeSsn) REFERENCES EMPLOYEE(EmployeeSsn) ;
ALTER TABLE STORE ADD FOREIGN KEY (SupplierParts) REFERENCES SUPPLIER(SupplierParts) ;
Once all of the above errors are corrected, your code does not through an error, and the foreign key on customer is created correctly:
https://www.db-fiddle.com/f/dVrG7Re6r68jaqYJ8HfR4P/0
From what I am seeing through your script you have 2 issues:
1st - You have a circular reference between the Payment and Customer tables. The Customer table is referencing the Payment table using the PaymentId foreign key, and the Payment table is referencing the Customer table using the CustomerId foreign key. You need to remove one of them so you'll eliminate the circular reference. If I were you I would remove the 1st one since you will most probably have multiple payments per customer but only one customer per payment. So keep the following script:
ALTER TABLE PAYMENT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
And remove this:
ALTER TABLE CUSTOMER ADD FOREIGN KEY (paymentid) REFERENCES PAYMENT(paymentid);
2nd - You are creating another circular reference when using the Product table because you are combining the product table with the customer and the payment tables twice. Here again you ideally would have a scenario where 1 customer uses multiple payments to pay for multiple products they are buying. So you don't need the following foreign key:
ALTER TABLE PRODUCT ADD FOREIGN KEY (CustomerId) REFERENCES CUSTOMER(CustomerId);
The reason for doing is because you only need one key to build a relationship between two tables. With regards to the 2nd point, you don't need to create a reference between the customer and the product because is already inferred in the two previous relationships you created; that between the Customer and the Payment and the other between the Payment and the Product. So there is a chained relationship which correlates the Customer to the Product they bought.

Unable to alter table with foreign key

My two empty tables:
CREATE TABLE person (
person_id SMALLINT UNSIGNED,
fname VARCHAR(20),
lname VARCHAR(20),
gender ENUM('m', 'f'),
birth_date DATE,
street VARCHAR(30),
city VARCHAR(20),
state VARCHAR(20),
country VARCHAR(20),
postal_code VARCHAR(20),
CONSTRAINT pk_person PRIMARY KEY (person_id)
);
create TABLE favorite_food (
person_id SMALLINT UNSIGNED,
food VARCHAR(20),
CONSTRAINT pk_favorite_food PRIMARY KEY (person_id, food),
CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id) REFERENCES person (person_id)
);
Needed modification:
ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT;
Result:
ERROR 1833 (HY000): Cannot change column 'person_id': used in a
foreign key constraint 'fk_fav_food_person_id' of table
'tom.favorite_food'
Why is this and is there a way around this without dropping the tables and redefining them?
This is probably because there already is data in person.person_id in any rows (NOT NULL). You can circumvent this by disabling foreign key checks
I believe the best way to handle this is to drop the foreign key reference from favorite_food, alter the column in person and then recreate the foreign key reference. That will properly recreate the index on which the key depends.

how to make a primary key a foreign key in another table?

These are my tables. I have a problem with the last one (Inscription) it doesn't accept CodeProjet as a foreign key. The error says table (Projet) doesn't have a primary key called CodeProjet but it does! I have used every trick that I know and nothing. I altered the table to add constraint, etc. Still nothing. I always get the same error. Here are the tables:
create database Gestion_Stages_Employe
create table Employe
(
NumEmploye int primary key,
NomEmploye varchar(15),
PrenomEmploye varchar(15),
SexeEmploye varchar(10),
DNaissEmploye date,
FonctionEmploye varchar(20)
)
create table TypeProjet
(
TypeProjet varchar(20) primary key,
libelleProjet varchar(20),
DureeProjet date,
)
create table Projet
(
CodeProjet int,
TypeProjet varchar(20),
DateDebut Date,
DateFin Date,
Constraint Pk_CodeProj primary key (CodeProjet,TypeProjet),
Constraint FK_TypeProj foreign key (TypeProjet) references TypeProjet(TypeProjet),
)
create table Inscription
(
NumEmploye int foreign key references Employe(NumEmploye),
CodeProjet int foreign key references Projet(CodeProjet),
dateiscription Date,
primary key (NumEmploye,CodeProjet),
)
As was mentioned in the comment, the Primary Key on the Projet table is a "composite key" (multiple columns are required to enforce uniqueness).
As a result, for your foreign key to work, you need to either remove "TypeProjet" from the primary key of Project (assuming CodeProjet is sufficient to uniquely identify a Projet), or you need to add TypeProjet to the Inscription table and define your foreign key with both columns, for example:
create table Inscription (
NumEmploye int foreign key references Employe(NumEmploye),
CodeProjet int,
dateiscription Date,
TypeProjet varchar(20),
Constraint fk_Inscription_project Foreign key (CodeProjet,TypeProjet) references Projet(CodeProjet,TypeProjet),
primary key (NumEmploye,CodeProjet),
)

Why can't I add a foreign key constraint on this?

CREATE TABLE usertypes (
userType INTEGER,
userName VARCHAR(12),
PRIMARY KEY(userType)
);
CREATE TABLE Users (
loginid CHAR(9),
name VARCHAR(15),
netid VARCHAR(15) NOT NULL,
password VARCHAR(15) NOT NULL,
userType INTEGER,
PRIMARY KEY (loginid),
UNIQUE (netid),
FOREIGN KEY (userType) REFERENCES usertypes(userType)
ON DELETE NO ACTION
);
CREATE TABLE Courses (
majorid CHAR(3),
cid CHAR (3),
secNum CHAR(2),
year CHAR(4),
semesterid CHAR(2),
profID CHAR(9),
PRIMARY KEY (majorid,cid,secNum,year,semesterid),
FOREIGN KEY (majorid) REFERENCES Majors (majorid),
FOREIGN KEY (profID) REFERENCES Users(loginid)
);
create table transcript(
cid char(3),
grade char(2),
primary key(cid, grade),
foreign key(cid) references courses(cid)
);
I can't add a foreign key cid in transcript. The foreign key for majorid in courses works fine but the one in transcript doesn't work.
Here's the error
Error Code: 1215. Cannot add foreign key constraint
Course.cid is not a key, so transcript cannot create a foreign key. Try the following:
CREATE TABLE Courses (
majorid CHAR(3),
cid CHAR (3),
secNum CHAR(2),
year CHAR(4),
semesterid CHAR(2),
profID CHAR(9),
PRIMARY KEY (majorid,cid,secNum,year,semesterid),
KEY (cid)
);
Short version is I don't think you can have a foreign key to something that isn't identified as a primary key or something with a unique constraint, see Foreign Key to non-primary key
I'm not sure how you are using the cid in the Courses table, if it is perhaps 110 and there is a Math 110 and a Physics 110. This has the problem of if someone has 110 on their transcript, does it reference Math or Physics?
If cid is a primary key, a unique value for each class, it should be a primary key all by itself. If you are in the situation of 110 for math and physics, you might be best served by adding a primary key that is unique for every row, such as an identity, auto incrementing key.