Foreign Key Constraint Error - MySQL - mysql

I am trying to create a database containing information from a game for an assignment but am having issues when creating the tables with assigning the primary and foreign keys. Any help would be amazing.
The error code I am getting is: #1215 - Cannot add foreign key constraint on table Boss. It creates the first table fine it just stops working and throws the error at the foreign key when creating table boss.
Within the item table the field Boss needs to be able have the same data entered for multiple different items.
CREATE TABLE item ( ID SERIAL, Name VARCHAR(35), Boss VARCHAR(25), Type VARCHAR(20), Slot VARCHAR(20), PRIMARY KEY (Name,Boss) );
CREATE TABLE boss ( ID SERIAL, Boss VARCHAR(25), Type VARCHAR(20), Location VARCHAR(20), Difficulty INT, PRIMARY KEY (ID, Location), FOREIGN KEY (Boss) REFERENCES item(Boss) );
CREATE TABLE dungeon ( ID SERIAL, Name VARCHAR(25), Location VARCHAR(20), Rating INT, PRIMARY KEY (Name), FOREIGN KEY (Location) REFERENCES boss(Location) );

I can see many things wrong with your db creation script, but I will only stick to the ones that immediately affect getting it to work in the first place:
You should always refer to another table through its primary key and nothing else.
Your references are put in the wrong tables. If you want to refer to a "boss" from "item" then you should do just that and not refer to "item" from "boss".
But the most important thing is that references should be of the same type as the primary keys they refer to.
A composite key is a bad idea when you don't really need one.
So, a working script would be:
CREATE TABLE dungeon ( ID BIGINT(20), Name VARCHAR(25), Location VARCHAR(20), Rating INT, PRIMARY KEY (ID) );
CREATE TABLE boss ( ID BIGINT(20), Type VARCHAR(20), LocationId BIGINT(20), Difficulty INT, PRIMARY KEY (ID), FOREIGN KEY (LocationId) REFERENCES dungeon (ID) );
CREATE TABLE item ( ID BIGINT(20), Name VARCHAR(35), BossId BIGINT(20), Type VARCHAR(20), Slot VARCHAR(20), PRIMARY KEY (ID), FOREIGN KEY (BossId) REFERENCES boss (ID) );
You can adjust it to your needs, but before doing that, I would suggest reading a good book on database design or -at least- a tutorial on basic relational databases principles.

Related

mysql issue, failing to add the foreign key constraint with missing index

I am new to mysql so apologies if this is a silly question. I am trying to create a new table and it is giving me the following error "Error Code: 1822 Failed to add the foreign key constraint. Missing index for constraint 'results_ibfk_2' in the referenced table 'predictors'" Apologies if the format isn't good, I am unaware on how mysql should be displayed on Stack. I have inputted data into the "predictors" table, however don't know how to add it into a Stack table. Also when I write Primary Key in brackets in the tables, that is just to signify that it is the primary key, it is not actually written in the table.
Thanks for your time,
Code
CREATE TABLE results (
Predictor_Result_ID INT NOT NULL AUTO_INCREMENT,
Predictor_ID INT,
Predictor_Name VARCHAR(50),
Match_ID INT,
Match_Name VARCHAR(50),
Match_Result VARCHAR(50),
Match_Specific_Result VARCHAR(50),
Match_Specific_Result_Plus VARCHAR(50),
Match_Prediction VARCHAR(50),
Match_Specific_Prediction VARCHAR(50),
Match_Specific_Prediction_Plus VARCHAR(50),
Match_Prediction_SuccessOrFail VARCHAR(50),
Match_Specific_Prediction_SuccessOrFail VARCHAR(50),
Match_Specific_Prediction_Plus_SuccessOrFail VARCHAR(50),
PRIMARY KEY (Predictor_Result_ID),
FOREIGN KEY (Predictor_ID) REFERENCES predictors(Predictor_ID),
FOREIGN KEY (Predictor_Name) REFERENCES predictors(Predictor_Name),
FOREIGN KEY (Match_ID) REFERENCES matches(Match_ID),
FOREIGN KEY (Match_Name) REFERENCES matches(Match_Name),
FOREIGN KEY (Match_Result) REFERENCES matches(Match_Result),
FOREIGN KEY (Match_Specific_Result) REFERENCES
matches(Match_Specific_Result),
FOREIGN KEY (Match_Specific_Result_Plus) REFERENCES
matches(Match_Specific_Result_Plus)
)
Tables
Table Title: matches
Match_ID (Primary Key)
Match_Name
Match_Result
Match_Specific_Result
Match_Specific_Result_Plus
Match_Name
----------------------------
------------
Table Title: predictors
Predictor_ID (Primary Key)
Predictor_Name
The message is telling you that the FOREIGN KEY constraint on results is referring to a column on the other table that is not indexed. Specifically you would need to create an index on predictors.Predictor_Name. This will probably also apply to matches.Match_Name and the other constraints you have defined.
However, it seems unlikely that you'd need constraints on ID as well as the other columns. Consider just using constraints on the IDs

Foreign Key Constraint Incorrectly Formed

I'm having an issue in which I can't create some tables because their foreign keys are "incorrectly formed." I don't know why I'm getting this error because the keys are of the same type and have unique names. The code is pretty straightforward:
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(ID) REFERENCES Listing(CarID)
);
CREATE TABLE Listing(
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarID),
FOREIGN KEY(CarID) REFERENCES Vehicle(ID)
);
If the primary key of Vehicle is (vin, ID) then a foreign key that references it must also have two columns, in the same order, with the same data types.
But in your case, your Listing table doesn't have a vin column, so it can't reference the primary key of Vehicle.
What would it mean for Listing to reference part of the primary key of Vehicle? There is no guarantee that only one row exists with a given value of ID in Vehicle. It could have multiple rows with the same ID and different vin values. So a Listing could potentially be the child of multiple vehicles, which probably doesn't make sense.
So you must either:
Add a vin column to Listing, so its foreign key can reference exactly one row by its primary key (both columns).
Modify the Vehicle table to make ID alone be its primary key.
Update:
I just noticed that you appear to have foreign keys in both tables. That's not usually needed. As I think about what you are trying to model, I would guess that a Listing has one or more Vehicles, right? So the Vehicle should reference its parent Listing. But a Listing does not need to reference a Vehicle.
So the following works:
First, create the parent table, because you can't make a foreign key until the parent table exists. In your case, the Listing is the parent table.
CREATE TABLE Listing(
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarID)
);
Then create the child table, with a foreign key that references its parent.
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(ID) REFERENCES Listing(CarID)
);
I tested on MySQL 5.7.27.
This is the correct way:
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID)
);
CREATE TABLE Listing(
CarVin VARCHAR(25),
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarVin, CarID),
FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID)
);
In your data model there are a listing and vehicles.
A vehicle can be in the Listing (or not). The Listing have n vehicles (so you have a 1 to n relation).
Each row in Listing have a reference to a vehicle, so it need the vehicle primary key fields (or some unique fields) to reference to it (The vehicle primary key is compound by "vin" and "ID" fields).
So the primary key in Listing should be compound by "vin" and "ID" too, like in Vehicle's table. It's a good practice to use integer autoincrement field as primary key for each table.
You need to add in table Listing "CarVin" field and then the foreign key in Listing will be FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID).
The foreign key will check, when you insert a Listing row, that the vehicle with the values CarVin and CarID exist.
To add a foreign key in table Vehicle too, you should disable foreign key check (SET FOREIGN_KEY_CHECKS=0;) until the tables will be created, because table Listing doesn't exist yet (if you create first table Vehicle). But I think it doesn't have sense in this case, at least you want ensure that all Vehicles are in Listing table.
To insert data you have to insert first a vehicle, and then add it to Listing table (foreign key is check, at least you disable foreign key check until the end), otherwise the foreign key check will fail.
In #"Bill Karwin"'s model you need first insert the Listing row and then the Vehicle.
MySql foreign key constraint documentation, each storage engine in MySql implements foreign key constraint in different way.
Both tables with foreign key constraint to each other:
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE Vehicle(
vin VARCHAR(25),
ID VARCHAR(20),
make VARCHAR(20),
model VARCHAR(20),
year_ VARCHAR(20),
condition_ VARCHAR(20),
PRIMARY KEY(vin, ID),
FOREIGN KEY(vin, ID) REFERENCES Listing(CarVin, CarID)
);
CREATE TABLE Listing(
CarVin VARCHAR(25),
CarID VARCHAR(20),
state_ VARCHAR(20),
price INT(10),
url VARCHAR(50),
PRIMARY KEY(CarVin, CarID),
FOREIGN KEY(CarVin, CarID) REFERENCES Vehicle(vin, ID)
);
SET FOREIGN_KEY_CHECKS = 1;

Error 1215: Cannot add foreign key constraint - MySQL (Simple Tables)

The current tables I have are as follows:
CREATE TABLE course(
CourseNum INT(11),
CourseName VARCHAR(30),
NumOfUnit INT(11),
PRIMARY KEY(CourseNum)
);
CREATE TABLE timeandloc(
CourseNum INT(11),
Quarter VARCHAR(20),
DayTime VARCHAR(40),
RoomNum INT,
PRIMARY KEY(CourseNum, Quarter, DayTime),
FOREIGN KEY(CourseNum) REFERENCES course (CourseNum)
);
I was able to add those fine using a query, but when I try to add this table:
CREATE TABLE student(
StudentName VARCHAR(30),
CourseNum INT(11),
Quarter VARCHAR(20),
PRIMARY KEY(StudentName, CourseNum, Quarter),
FOREIGN KEY(CourseNum) REFERENCES course(CourseNum),
FOREIGN KEY(Quarter) REFERENCES timeandloc(Quarter)
);
I get
Error code: 1215. Cannot add foreign key constraint.
It seems to be this line that's the culprit:
FOREIGN KEY(Quarter) REFERENCES timeandloc(Quarter)
When I try to add the table without that line, everything works fine without a hitch.
I'm very new to MySQL and databases in general so I'm not sure what's wrong. Any help would be great. Thanks.
create a separate index on Quarter field in timeandloc table and then create problematic create table query.
alter table timeandloc add index idx_Quarter(Quarter);
CREATE TABLE student(
StudentName VARCHAR(30),
CourseNum INT(11),
Quarter VARCHAR(20),
PRIMARY KEY(StudentName, CourseNum, Quarter),
FOREIGN KEY(CourseNum) REFERENCES course(CourseNum),
FOREIGN KEY(Quarter) REFERENCES timeandloc(Quarter)
);
Update:
For performance point of view joining field in both tables (parent/child) should be indexed. When we create foreign key then mysql itself create an index on the field we create foreign key but could not allow without index on referenced column in referenced table. As index works from left to right, so in your case index for Quarter column will not be used from primary key, so need to create a separate index on it.

Error 1215: Why is it happening?

I am confused as to why error 1215: cannot add foreign key constraint is occurring in my code. Does anybody have any ideas?
The first four tables create themselves fine, but the error is thrown when I try to create the Stars table. I am not sure what's going wrong, as the keys being referenced are primary keys and so they must be unique and non-null. Plus, those keys exist as the previous tables have been created first. It might just be a stupid mistake I made, but its better to have fresh eyes look at it, right?
This database is simplistic as it is because I'm doing it for a school assignment.
create table MovieExec
(
execName varchar(40),
certNum numeric(30, 0),
address varchar(50),
networth real,
primary key(execName),
unique key(certNum)
);
create table Stud
(
studName varchar(30),
address varchar(50),
presCNum numeric(30, 0),
primary key(studName),
foreign key (presCNum) references MovieExec(certNum)
);
create table MovieStar(
starName varchar(30),
address varchar(50),
gender varchar(1),
birthdate date,
primary key(starName)
);
create table Movies
(
movieTitle varchar(30),
movieYear numeric(4,0),
length numeric(3,0),
genre varchar(30),
studioName varchar(30),
producerCNum numeric(30, 0),
primary key (movieTitle, movieYear),
foreign key (producerCNum) references MovieExec(certNum),
foreign key (studioName) references Stud(studName)
);
create table Stars
(
movieTitle varchar(30),
movieYear numeric(4,0),
starName varchar(30),
primary key (movieTitle, movieYear, starName),
foreign key (movieTitle) references Movies(movieTitle),
foreign key (movieYear) references Movies(movieYear),
foreign key (starName) references MovieStar(starName)
);
It should be a composite foreign key for the title and the year:
foreign key (movieTitle, movieYear) references Movies(movieTitle, movieYear),
foreign key (starName) references MovieStar(starName)
It should be composite because that's the exact PK of Movies table and that's the only UNIQUE combination there currently available.
Then as #CBroe mentioned in their answer it would be a good idea to index the Stars.starName column.
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html:
“[…] in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order”
In your Movies table, you only have a primary key on the combination (movieTitle, movieYear) – but movieYear is not the first column in that key, and therefor
foreign key (movieYear) references Movies(movieYear)
in your CREATE statement for the stars table fails.
Add a key on Movies.movieYear – then creating a foreign key referencing that column on the stars table will work.
FYI: MySQL has a YEAR data type – you should use that, instead of a NUMERIC for your movie year.
And you are mixing singular and plural in your table names. Convention is to use the singular of the object that a table holds as table name; but at least you should try and be consistent with your naming scheme.

How to create tables on putty if they all depend on each other by using mysql syntax?

I have to create a number of tables for my project and each one of them has a foreign key besides their primary key. I know how to create a table on putty without the foreign key but if they are all depends on each other, then how to create them individually ?
For example, if I want to create table A, B and C
CREATE TABLE PROFESSOR
(
SSN numeric(9) primary key,
PNAME varchar(20),
CITY varchar(20),
STREETADDRESS varchar(50),
STATE char(2),
ZIP numeric(5),
AREACODE numeric(3),
PHONENUMBER numeric(7),
SEX char(1),
TITLE char(4),
SALARY float(9),
foreign key (DNUM) references DEPARTMENT(DNUM)
);
CREATE TABLE DEPARTMENT
(
DNUM numeric(1) primary key,
DNAME varchar(20),
DPHONE numeric(10),
OFFICELOCATION varchar(20),
foreign key (CWID) references STUDENT(CWID)
);
CREATE TABLE STUDENT
(
CWID numeric(9) primary key,
FNAME varchar(20),
LNAME varchar(20),
SADDRESS varchar(50),
SPHONE numeric(10),
foreign key (DNUM) references DEPARTMENT(DNUM)
);
I'm using Putty to create table and I have to run them separately. The thing is if I run the scrip separately for each table, it's going to give me an error, because the table that has the foreign key does not create yet. How am I going to fix it ? and is there a work around way on solving this problem ? Thank you.
If I run the script for creating table separately, it will give me an error