MySQL error 1215 Cannot add Foreign key constraint

2019-07-24 21:55发布

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!

3条回答
够拽才男人
2楼-- · 2019-07-24 22:42

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.

查看更多
地球回转人心会变
3楼-- · 2019-07-24 22:44

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.

查看更多
倾城 Initia
4楼-- · 2019-07-24 22:55

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.

查看更多
登录 后发表回答