MySQL Foreign Keys Issue - mysql

I have 3 table: CD, Song and Song_Details which is a relationship between CD & Song:
create table Song(
ID int not null auto_increment,
Title varchar(255) not null,
Length float not null,
primary key (ID, Title)
);
create table CD(
Title varchar(255) not null,
CD_Number int not null,
primary key (Title, CD_Number)
);
Create table Song_Details(
CD_Title varchar(255) not null,
Song_Title varchar(255) not null,
Track_Number int not null,
primary key(CD_Title, Song_Title),
foreign key(CD_Title) references CD(Title),
foreign key(Song_Title) references Song(Title)
);
I have managed to find out that this line in Song_Details:
foreign key(Song_Title) references Song(Title) is throwing the Error 1215(HY000): Cannot add foreign key constraint;
Could anyone help me see based on my table, what could be causing this issue?

Two things. The auto_increment key would normally be the foreign key. Second, you need to make your reference to all the keys defined as the primary or unique key for the table (I don't advise making foreign key references to non-unique keys although MySQL does all that).
So:
create table Song (
Song_ID int not null auto_increment,
Title varchar(255) not null,
Length float not null,
primary key (ID),
unique (title)
);
create table CD (
CD_Id int auto_increment primary key,
Title varchar(255) not null,
CD_Number int not null,
unique (Title, CD_Number)
);
Create table Song_Details(
CD_ID varchar(255) not null,
Song_Id varchar(255) not null,
Track_Number int not null,
primary key(CD_ID, Song_ID),
foreign key(CD_ID) references CD(CD_ID),
foreign key(Song_ID) references Song(Song_ID)
);
Notes:
Use the primary key relationships for the foreign key definitions.
I like to have the primary keys include the table name. That way, the primary key can have the same name as the corresponding foreign keys.
Don't put the titles in more than one place. They belong in the entity tables. Autoincremented ids can then be used to access the titles.

Related

How to solve the errno: 150 "Foreign key constraint is incorrectly formed" even though my constraint is correct?

I am trying to create three tables :
Hotel Table
CREATE TABLE Hotels(
HotelID VARCHAR(30) NOT NULL,
Name VARCHAR(30) NOT NULL,
City VARCHAR(30) NOT NULL,
Rating VARCHAR(30) NOT NULL,
Description VARCHAR(500) NOT NULL,
PRIMARY KEY (HotelID)
)
Rooms table
CREATE TABLE Rooms (
HotelID VARCHAR(30) NOT NULL,
Room_Number INT NOT NULL,
Price_Rate INT NOT NULL,
Type VARCHAR(30) NOT NULL,
PRIMARY KEY(HotelID, Room_Number),
FOREIGN KEY(HotelID) REFERENCES hotels(HotelID)
)
BookingInfo Table
CREATE TABLE BookingInfo (
HotelID VARCHAR(30) NOT NULL,
UserID VARCHAR(30) NOT NULL,
Room_Number INT NOT NULL,
Arrival_Date DATE NOT NULL,
Departure_Date DATE NOT NULL,
PRIMARY KEY(UserID, HotelID, Room_Number, Arrival_Date),
FOREIGN KEY(HotelID) REFERENCES hotels(HotelID),
FOREIGN KEY(UserID) REFERENCES users(UserID),
FOREIGN KEY (Room_Number) REFERENCES rooms(Room_Number)
)
But when I try to create the third table I am getting errno: 150 "Foreign key constraint is incorrectly formed".
Moreover, when I delete FOREIGN KEY (Room_Number) REFERENCES rooms(Room_Number) the table gets created successfully. But I don't understand why it is not accepting FOREIGN KEY (Room_Number) REFERENCES rooms(Room_Number).
I have also tried to alter the table and change data type but still didn't get any success. Can anyone please point out my the mistake in this codes.
The primary key of Rooms is two columns: (HotelID, Room_Number).
The foreign key in BookingInfo is one column: (Room_Number).
A foreign key should reference the whole primary key of the referenced table. If that primary key has more than one column, all of the columns must be referenced by the foreign key, and in the same order.
Caveat that is not standard SQL and specific to InnoDB: InnoDB allows a foreign key to reference part of a multi-column key in the referenced table, as long as the column is the leftmost column of that key. But in your case, you are referencing the second from the left column of that key, Room_Number. So it's not allowed. And in my opinion, it's a bad idea anyway to reference part of the key, because it leads to weird data anomalies.
REFERENCES rooms(Room_Number) room_number has to be a key or the first node of a multi column key
'In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order.' https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
Thanks a lot for the guidance. This code has worked for me :
CREATE TABLE BookingInfo (
HotelID VARCHAR(30) NOT NULL,
UserID VARCHAR(30) NOT NULL,
Room_Number INT NOT NULL,
Arrival_Date DATE NOT NULL,
Departure_Date DATE NOT NULL,
PRIMARY KEY(UserID, HotelID, Room_Number, Arrival_Date),
FOREIGN KEY(UserID) REFERENCES users(UserID),
FOREIGN KEY(HotelID,Room_Number) REFERENCES rooms(HotelID,Room_Number)
)

SQL Foregin key "Does not exist"

I've been trying to connect my tables with with Foregin key, but I always get an error that my veriable does not exists. I set index for my primary key for counting. My code for table with primary key looks like this:
CREATE TABLE data_animal(
name VARCHAR(30) NOT NULL,
birth_date DATE NOT NULL,
sex ENUM('Male', 'Female') NOT NULL,
animal_car ENUM('Brave', 'Lazy', 'Agressive', 'Nice', 'Nervous') NOT NULL,
des VARCHAR (250),
type ENUM('Cat', 'Dog', 'Bird', 'Snake', 'Fish') NOT NULL,
steril ENUM('Yes', 'No') NOT NULL,
Breed VARCHAR(20) NOT NULL,
id_animal INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE INDEX idx_id_animal
ON data_animal (id_animal);
My code for another table where I need id_animal as foregin key is:
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
);
I tried few defferent approaches how to insert foreign key as:
id_animal int FOREIGN KEY REFERENCES data_animal(id_animal)
or
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
)ENGINE=INNODB;
or
CONSTRAINT data_animal FOREIGN KEY (id_animal)
REFERENCES data_animal(id_animal)
I always get this error:
(Key column 'id_animal' doesn't exist in table)
I don't know what else could be wrong. Thanks for the help.
The foreign key has to be a column in the table you're defining, so you need to add an id_animal column to the photos table before you can make it a foreign key.
CREATE TABLE photo(
id_picture INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
id_animal INT,
FOREIGN KEY (id_animal) REFERENCES data_animal (id_animal)
);

How to fix foreign key errors in MySQL?

I am using Ubuntu on Virtualbox. I’m trying to write my SQL for a database however whenever I create one with a Foreign Key it always returns an error
CREATE TABLE Vehicles (Vehicle ID int, Vehicle Type VARCHAR(255), Model VARCHAR(255), Engine Size float, Condition VARCHAR(255), Price float, PRIMARY KEY (Vehicle ID), FOREIGN KEY (Model) REFERENCES Models(Model));
Can you help me please? Below are my SQL table statements to create the Database so maybe there is an error in my code?
CREATE TABLE Models (
Model_ID int NOT NULL,
Manufacturer VARCHAR(255) NOT NULL,
Model_name VARCHAR(255) NOT NULL,
Wheel_Drive_Type VARCHAR(255) NOT NULL,
PRIMARY KEY (Model_ID));
CREATE TABLE Customers (
Customer_ID int NOT NULL,
Customer_name VARCHAR(255) NOT NULL,
Customer_Contact_number VARCHAR(255) NOT NULL,
Customer_Address VARCHAR(255) NOT NULL,
Customer_Email VARCHAR(255) NOT NULL,
PRIMARY KEY (Customer_ID));
CREATE TABLE Vehicles (
Vehicle_ID int NOT NULL,
Vehicle_Type VARCHAR(255) NOT NULL,
Model_name VARCHAR(255) NOT NULL,
Engine_Size float NOT NULL,
Condition VARCHAR(255) NOT NULL,
Price float NOT NULL,
PRIMARY KEY (Vehicle_ID),
FOREIGN KEY (Model) REFERENCES Models(Model_name));
CREATE TABLE Enquiries (
Enquiry_ID int NOT NULL,
Vehicle int NOT NULL,
Customer_ID int NOT NULL,
Additional_information VARCHAR(255) NOT NULL,
PRIMARY KEY (Enquiry_ID),
FOREIGN KEY (Vehicle_ID) REFERENCES Vehicles(Vehicle_ID),
FOREIGN KEY (Customer_ID) REFERENCES Customers(Customer_ID));
CREATE TABLE Sales (
Sales_ID int NOT NULL,
Vehicle_ID int NOT NULL,
Customer_ID int NOT NULL,
Date_of_sale VARCHAR(255) NOT NULL,
Sale_Type VARCHAR(255) NOT NULL,
PRIMARY KEY (Sale_ID),
FOREIGN KEY (Vehicle_ID) REFERENCES Vehicles(Vehicle_ID),
FOREIGN KEY (Customer_ID) REFERENCES Customers(Customer_ID));
Your SQL has spaces as part of the identifier, which is not allowed. For example (Customer ID) rather than (Customer_ID). That's true throughout your example code. Also, when working with foreign keys, be sure you have the same type, including signed/unsigned. If you are using utf8mb4, a varchar index is limited to 191 rather than 255, and you'll want your field referenced with a foreign key to also be an index. (This advice MIGHT be obsolete, depending on your version, but the spaces are a problem.)
The column you reference has to have an index, but there's no index on the Model_name column in Models. You need to add:
INDEX (Model_name)
CREATE TABLE Models (
Model_ID int NOT NULL,
Manufacturer VARCHAR(255) NOT NULL,
Model_name VARCHAR(255) NOT NULL,
Wheel_Drive_Type VARCHAR(255) NOT NULL,
PRIMARY KEY (Model_ID)
INDEX (Model_name));
I suggest you take the Model_name column out of Vehicles, and replace it with Model_ID. It's usually best to have foreign keys point to primary keys.
The problem seems to be with this segment FOREIGN KEY (Model) REFERENCES Models(Model));
Model_ID is the primary key of your table Models, hence the statement segment should be FOREIGN KEY (Model) REFERENCES Models(Model_ID));
Also, the foreign key should be the primary key of the reference table with the same data type. Your DDL for Vehicles should look like following
CREATE TABLE Vehicles (
Vehicle_ID int,
Vehicle_Type VARCHAR(255),
Model_ID int,
Engine_Size float,
Condition VARCHAR(255),
Price float,
PRIMARY KEY (Vehicle ID),
FOREIGN KEY (Model_ID) REFERENCES Models(Model_ID)
);

trying to relate two table together

so pretty new to SQL I created 2 tables which I wanted to be related to one another but I'm getting an error "#1215 - Cannot add foreign key constraint" can someone point me to the right direction of this problem?
CREATE TABLE movie(
id INT(1) NOT NULL AUTO_INCREMENT,
nearname VARCHAR(25) NOT NULL,
release_date DATE NOT NULL,
lang VARCHAR(10) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT same_movie FOREIGN KEY(id) REFERENCES movie_cast(movie_id)
);
CREATE TABLE movie_cast(
movie_id INT(1) NOT NULL AUTO_INCREMENT,
director_name VARCHAR(20) NOT NULL,
actor_name VARCHAR(20) NOT NULL,
actress_name VARCHAR(20) NOT NULL,
PRIMARY KEY(movie_id),
CONSTRAINT same_movie FOREIGN KEY(movie_id) REFERENCES movie(id)
);
You need to refer to the same column name as the primary key. In this case, it is called id:
CONSTRAINT same_movie FOREIGN KEY(movie_id) REFERENCES movie_cast(id)
Of course, your DDL doesn't define movie_cast. So, I am guessing the second table should be something like:
CREATE TABLE movie_cast (
id INT NOT NULL AUTO_INCREMENT,
movie_id int not null,
cast_name varchar(255)
PRIMARY KEY(id),
CONSTRAINT fk_movie_cast_movie FOREIGN KEY(movie_id) REFERENCES movie(movie_id)
);

Can not Add External Index Constraints

This is the exact error that WAMP returns when I run the child code from an external file called entries.txt
ERROR 1215 (HY000): Can not Add External Index Constraints
I need to be able to connect the parent tables to the child table so that links can be made between the tables easily.
The question states:
Create and populate a third table called entries, again using query scripts.
This table should contain foreign keys to allow sensible links to be
made with the other two tables, together with the dates of each exam.
Parent Tables:
CREATE TABLE IF NOT EXISTS students(
student_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20) NOT NULL,
middle_name VARCHAR(20),
last_name VARCHAR(40) NOT NULL,
email VARCHAR(60) NOT NULL,
password CHAR(40) NOT NULL,
reg_date DATETIME NOT NULL,
PRIMARY KEY (student_id),
UNIQUE (email));
CREATE TABLE IF NOT EXISTS subjects(
subject_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
subject_name CHAR(30) NOT NULL,
level_of_entry VARCHAR(10) NOT NULL,
exam_board CHAR(20) NOT NULL,
PRIMARY KEY (subject_id));
Child Table:
CREATE TABLE IF NOT EXISTS entries(
date_of_exam DATETIME NOT NULL,
first_name VARCHAR,
middle_name VARCHAR,
last_name VARCHAR,
subject_name CHAR,
level_of_entry VARCHAR,
exam_board CHAR,
INDEX idx_first_name(first_name),
INDEX idx_middle_name(middle_name),
INDEX idx_last_name(last_name),
INDEX idx_subject_name(subject_name),
INDEX idx_level_of_entry(level_of_entry),
INDEX idx_exam_board(exam_board),
PRIMARY KEY (date_of_exam),
CONSTRAINT fk_first_name FOREIGN KEY (first_name) REFERENCES students(first_name),
CONSTRAINT fk_middle_name FOREIGN KEY (middle_name) REFERENCES students(middle_name),
CONSTRAINT fk_last_name FOREIGN KEY (last_name) REFERENCES students(last_name),
CONSTRAINT fk_subject_name FOREIGN KEY (subject_name) REFERENCES subjects(subject_name),
CONSTRAINT fk_level_of_entry FOREIGN KEY (level_of_entry) REFERENCES subjects(level_of_entry),
CONSTRAINT fk_exam_board FOREIGN KEY (exam_board) REFERENCES subjects(exam_board)
)ENGINE=InnoDB;
A foreign key in the child table must reference the primary key of the parent table only. You don't need to create clones of every attribute column of the parent tables, just the primary key column. If you need to read the other attributes, you'd write a query with a JOIN.
CREATE TABLE IF NOT EXISTS entries(
student_id INT UNSIGNED NOT NULL,
subject_id INT UNSIGNED NOT NULL,
date_of_exam DATETIME NOT NULL,
PRIMARY KEY (student_id, subject_id, date_of_exam),
CONSTRAINT fk_student FOREIGN KEY (student_id) REFERENCES students(student_id),
CONSTRAINT fk_subject FOREIGN KEY (subject_id) REFERENCES subjects(subject_id),
)ENGINE=InnoDB;