Mysql Cannot add foreign key constraint weird error [duplicate] - mysql

I have to create this table with all these composite keys.
prospect(custname, carmake, carmodel, caryear, carextcolour, cartrim, optioncode)
All the fields above are underlined to show they are primary. So 7 primary composite keys.
For some reason this does not create the table.
CREATE TABLE prospect
(Custname VARCHAR(25) NOT NULL,
Carmake VARCHAR(25) NOT NULL,
Carmodel VARCHAR(20) NOT NULL,
Caryear VARCHAR(4) NOT NULL,
Carextcolour VARCHAR(10) NOT NULL,
Cartrim VARCHAR(10) NOT NULL,
Optioncode CHAR(4),
CONSTRAINT pkprospect PRIMARY KEY (Custname, Carmake, Carmodel, Caryear, Carextcolour, Cartrim, Optioncode),
CONSTRAINT fkprospect FOREIGN KEY (Custname) REFERENCES customer(Custname),
CONSTRAINT fk2prospect FOREIGN KEY (Carmake) REFERENCES car(Carmake),
CONSTRAINT fk3prospect FOREIGN KEY (Carmodel) REFERENCES car(Carmodel),
CONSTRAINT fk4prospect FOREIGN KEY (Caryear) REFERENCES car(Caryear),
CONSTRAINT fk5prospect FOREIGN KEY (Carextcolour) REFERENCES car(Carextcolour),
CONSTRAINT fk6prospect FOREIGN KEY (Cartrim) REFERENCES car(Cartrim),
CONSTRAINT fk7prospect FOREIGN KEY (Optioncode) REFERENCES optiontable(Optioncode)
);
the code i'm using to create this table full of composite keys.

You should make one foreign key constraint referencing the full primary or unique key of each referenced table. You can't make separate foreign keys to individual columns in the middle of the references table's primary key.
CREATE TABLE prospect
(Custname VARCHAR(25) NOT NULL,
Carmake VARCHAR(25) NOT NULL,
Carmodel VARCHAR(20) NOT NULL,
Caryear VARCHAR(4) NOT NULL,
Carextcolour VARCHAR(10) NOT NULL,
Cartrim VARCHAR(10) NOT NULL,
Optioncode CHAR(4),
CONSTRAINT pkprospect PRIMARY KEY (Custname, Carmake, Carmodel, Caryear, Carextcolour, Cartrim, Optioncode),
CONSTRAINT fkprospect FOREIGN KEY (Custname) REFERENCES customer(Custname),
CONSTRAINT fk2prospect FOREIGN KEY (Carmake, Carmodel, Caryear, Carextcolour, Cartrim)
REFERENCES car(Carmake, Carmodel, Caryear, Carextcolour, Cartrim),
CONSTRAINT fk7prospect FOREIGN KEY (Optioncode) REFERENCES optiontable(Optioncode)
);
I used the word should above because InnoDB is actually a bit more lenient than the ANSI/ISO SQL standard when it comes to foreign keys. Standard SQL says the columns of the foreign key must be the full list of columns of the referenced primary or unique key.
InnoDB permits you to use a subset of columns, as long as they're a left-prefix of those columns. But you shouldn't do that, because you get really confusing results when a child row may reference multiple rows in its parent table.

Try this: Creating table with primary key for the first step and then use alter table command for foreign keys and add them.

If you have not created the reference tables, you cannot create this table. You can first create all your reference tables and then enter FK submissions with alter table.

Related

How to set primary Key column name when two or more foreign keys are used?

create table teach_enroll(
instructor_id varchar(64) not null,
class_id varchar(64)not null,
course_id varchar(64)not null,
student_id varchar(64) not null,
foreign key (instructor_id) references instructor(id),
foreign key (class_id) references class(id),
foreign key(course_id)references course_type(id),
foreign key (student_id)references student(id),
CONSTRAINT ENROLL_ID primary key (class_id,course_id,student_id)
);
select * from teach_enroll;
I am trying to name my primary key column as ENROLL_ID but the constraint keyword is not helping when I query select * from teach_enroll I get only instructor_id,class_id,course_id,student_id in separate columns but I cannot see the primary key column :)
Your primary key consists of three (3) columns, not a single column, because that is the way you defined it. This means that the combination of those three column must be unique for each row in the table although any given column defined as the key may not be. You cannot apply a single name to three columns.
This means that your foreign key constraint will name all 3 columns. Assuming the column names are the same in both tables, then:
CONSTRAINT FOREIGN KEY (class_id,course_id,student_id)
REFERENCES teach_enroll(class_id,course_id,student_id)

Why KEY has automatically created when I make fk constraint for field?

I am creating the table with this syntax:
CREATE TABLE movies_genres
(
id BIGINT AUTO_INCREMENT,
movie_id INT NOT NULL,
genre_id INT NOT NULL,
PRIMARY KEY (id),
CONSTRAINT `fk_movie_id` FOREIGN KEY (movie_id) REFERENCES movies(id),
CONSTRAINT `fk_genre_id` FOREIGN KEY (genre_id) REFERENCES genres(id),
CONSTRAINT unique_id_pair UNIQUE(movie_id, genre_id)
);
But then I look at the info about the table in MySQL Workbench I see:
CREATE TABLE `movies_genres` (
`id` bigint NOT NULL AUTO_INCREMENT,
`movie_id` int NOT NULL,
`genre_id` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_id_pair` (`movie_id`,`genre_id`),
KEY `fk_genre_id` (`genre_id`),
CONSTRAINT `fk_genre_id` FOREIGN KEY (`genre_id`) REFERENCES `genres` (`id`),
CONSTRAINT `fk_movie_id` FOREIGN KEY (`movie_id`) REFERENCES `movies` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Why this line of code has generated?
KEY `fk_genre_id` (`genre_id`)
Also I see that extra index was created that I didn't order...
Screenshot with extra index
https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html says:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist.
(emphasis mine)
(Bill gave the answer; this is providing another tip.)
Get rid of id from the table and change to these two indexes:
PRIMARY KEY (`movie_id`,`genre_id`),
KEY `fk_genre_id` (`genre_id`),
That will make some of your uses of this many-to-many table run faster. It will also shrink the table size.
If need id
Since you need id for single-row deletion and updating, keep id, but use
PRIMARY KEY (id)
INDEX(`movie_id`, `genre_id`),
INDEX(`genre_id`, `movie_id`),
The PK will continue to make Delete/Update efficient; the other two indexes will make the many-to-many JOIN efficient.

SQL Error, unable to create table on a certain format

I am facing an error when creating a table between the following two statement
CREATE TABLE SECTION (
cid varchar(10) not null,
sno varchar(3) not null,
primary key (cid, sno),
foreign key (cid) references COURSE (cid)
);
CREATE TABLE ROUND_RELEASE (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid) references SECTION (cid),
foreign key (sno) references SECTION (sno),
foreign key (rid) references ROUND (rid)
);
Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'round_release_ibfk_2' in the referenced table 'section'
However, when I try to swap the primary key order in SECTION table, I am able to create both table without error
CREATE TABLE SECTION (
cid varchar(10) not null,
sno varchar(3) not null,
primary key (**sno, cid**),
foreign key (cid) references COURSE (cid)
);
CREATE TABLE ROUND_RELEASE (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid) references SECTION (cid),
foreign key (sno) references SECTION (sno),
foreign key (rid) references ROUND (rid)
);
The follow code above works, and I only swap the attribute, from my knowledge, the order does not matter, thus I am quite puzzled by why is this occurring.
Any guidance on this? Thanks!
Based on the error message, I assume that you are using MySQL.
What you are seeing is a documented behavior:
In the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Let me pinpoint, however, that your code probably does not do what you really want. You probably should be creating a compound foreign key, that references the tuples of columns, rather than one foreign key per column:
create table round_release (
cid varchar(10) not null,
sno varchar(3) not null,
rid int not null,
foreign key (cid, sno) references section(cid, sno),
foreign key (rid) references round(rid)
);
One last thing to note is that your round_release table has no primary key defined; this is not a good practice, and might hurt you in several ways in the future. So, do create a primary key for the table, either as a separate column (possibly auto-incremented), or as a combination of existing columns.

MySql 5.6.17 Error #1215 - Cannot add foreign key constraint

I'm tryin to create a table "SIGNATURE" in my database I want this table to have a double primary key and add a foreign key constraint to both primary key that references table "TRAITEMENT"
CREATE TABLE TRAITEMENT (
id INTEGER NOT NULL,
dateHeurePrevue DATETIME NOT NULL,
commentaire LONGTEXT,
dateValidation TIMESTAMP,
CONSTRAINT PK PRIMARY KEY (id,dateHeurePrevue),
CONSTRAINT FK_traitement_consigne FOREIGN KEY (id) REFERENCES consigne(id)) ENGINE=InnoDB;
create unique index id_dateheureprevue on traitement(id, dateheureprevue);
CREATE TABLE SIGNATURE (
id INTEGER NOT NULL,
idPersonne INTEGER NOT NULL,
dateTimeTraitement DATETIME NOT NULL,
retard INTEGER,
motifRetard INTEGER,
heureEffectiveTraitement DATETIME NOT NULL,
CONSTRAINT PK PRIMARY KEY (id,dateTimeTraitement),
CONSTRAINT FK_id FOREIGN KEY (id) REFERENCES traitement(id),
CONSTRAINT FK_idPersonne FOREIGN KEY (idPersonne) REFERENCES personne(id),
CONSTRAINT FK_motifRetard FOREIGN KEY (motifRetard) REFERENCES retard(id),
CONSTRAINT FK_dateTimeTraitement FOREIGN KEY (dateTimeTraitement) REFERENCES traitement(dateHeurePrevue))ENGINE=InnoDB;
create unique index id_dateTimetraitement on signature(id, dateTimeTraitement);
Obviously ( I tried to remove it and it worked fine) the problem comes from this forign key :
CONSTRAINT FK_dateTimeTraitement FOREIGN KEY (dateTimeTraitement) REFERENCES traitement(dateHeurePrevue)
I don't understand, i don't see any conflicts of type,keys...
If anyone can help me solve this problem...
Thanks in advance
Your foreign key must be exactly equal to the primary key fields, so:
CONSTRAINT FK_dateTimeTraitement FOREIGN KEY (id, dateTimeTraitement) REFERENCES traitement(id, dateHeurePrevue)

MySQL error 1215 Cannot add Foreign key constraint - FK in different tables

im new on mysql workbench, and i tried so many things to put my script working but i simply cant... Ive got these tables:
CREATE TABLE Utilizador (email varchar(40) not null, nome varchar(50)
not null, dataNascimento date, profissao varchar(50) not null,
reputacao double(3,2) unsigned not null, constraint pk_Utilizador
primary key(email))
This is the first table created!
CREATE TABLE POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, coordenadaX int, coordenadaY int,
descricaoPOI varchar(200), constraint pk_POI primary key(email,
designacaoPOI), constraint fk_POI foreign key(email) references
Utilizador(email) on delete cascade)
This is the second table created!
CREATE TABLE Utilizador_POI (email varchar(40) not null, designacaoPOI
varchar(10) not null, constraint pk_Utilizador_POI primary key(email,
designacaoPOI), constraint fk1_Utilizador_POI foreign key(email)
references Utilizador(email) on delete cascade, constraint
fk2_Utilizador_POI foreign key(designacaoPOI) references
POI(designacaoPOI) on delete cascade)
This table gives me the error: Error Code: 1215. Cannot add foreign key constraint
I did some tests and im almost sure that the problem is in the foreign key "designacaoPOI". The other FK ("email") dont give me any error, so maybe the problem is in the Table POI?
Thanks in advanced!
The problem here is twofold:
1/ Use IDs for PRIMARY KEYs
You should be using IDs for primary keys rather than VARCHARs or anything that has any real-world "business meaning". If you want the email to be unique within the Utilizador table, the combination of email and designacaoPOI to be unique in the POI table, and the same combination (email and designacaoPOI) to be unique in Utilizador_POI, you should be using UNIQUE KEY constraints rather than PRIMARY KEY constraints.
2/ You cannot DELETE CASCADE on a FOREIGN KEY that doesn't reference the PRIMARY KEY
In your third table, Utilizador_POI, you have two FOREIGN KEYs references POI. Unfortunately, the PRIMARY KEY on POI is a composite key, so MySQL has no idea how to handle a DELETE CASCADE, as there is not a one-to-one relationship between the FOREIGN KEY in Utilizador_POI and the PRIMARY KEY of POI.
If you change your tables to all have a PRIMARY KEY of ID, as follows:
CREATE TABLE blah (
id INT(9) AUTO_INCREMENT NOT NULL
....
PRIMARY KEY (id)
);
Then you can reference each table by ID, and both your FOREIGN KEYs and DELETE CASCADEs will work.
I think the problem is that Utilizador_POI.email references POI.email, which itself references Utilizador.email. MySQL is probably upset at the double-linking.
Also, since there seems to be a many-to-many relationship between Utilizador and POI, I think the structure of Utilizador_POI isn't what you really want. Instead, Utilizador_POI should reference a primary key from Utilizador, and a matching primary key from POI.
The problem is in your second table. Your primary key is (email,designacaoPOI), when you try to reference that in your table it gives you error because of this:
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
For it to work, either change the order of your second tale PRIMARY KEY :
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email), -- changed the order
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
or add an index for designacaoPOI:
CREATE TABLE POI (
email VARCHAR(40) NOT NULL,
designacaoPOI VARCHAR(10) NOT NULL,
coordenadaX INT,
coordenadaY INT,
descricaoPOI VARCHAR(200),
CONSTRAINT pk_POI PRIMARY KEY (designacaoPOI,email),
KEY key_designacaoPOI(designacaoPOI), -- added index for that column
CONSTRAINT fk_POI FOREIGN KEY (email)
REFERENCES Utilizador(email) ON DELETE CASCADE
);
sqlfiddle demo
Either of these solutions will let you create your third table without errors.