简体   繁体   中英

MySQL Foreign Key “ON DELETE CASCADE” across 3 tables

I have 3 tables in my DB (there are more, but there are no connections to these yet)

  • table "molecule" with column id
  • table "descriptor" with columns "id" and "molecule_id" and a foreign key referencing "molecule.id"
  • table "tDepDescriptor" with columns "id" and "descriptor_id" and a foreign key referencing "descriptor.id "

(each table has more columns, but none of these act as foreign keys or anything like that)

All foreign keys have "on delete cascade" specified, all ids are unsigned int(5).

Now, if I try to delete an entry in "molecule" for which there are referencing entries in "descriptor" and "tDepDescriptor" nothing happens as if the foreign keys were set to "on update restrict", no error is given. If I delete an entry in "descriptor", all referencing entries in "tDepDescriptor" are deleted like they should. The same happens if I try to delete an entry in "molecule" for which there are referencing entries in "descriptor", but no referencing entries to those "descriptor"-entries in "tDepDescriptor". So "on delete cascade" works for two tables, but the "cascade" does not seem to be passed on when three tables are involved.

What the tables are supposed to do is: When I want to delete an entry in "molecule", all referencing entries in "descriptor" are deleted. And therefore all entries in "tDepDescriptor" that have a reference to one of the deleted entries in "descriptor" are also deleted.

mysql server version is 5.1, engine is InnoDB

Is hope someone could follow this complicated explanation and can help me.

//EDIT: Found the problem. Seems to be a problem with phpMyAdmin, not with the database. clicking on delete in PMA did not work, but coding the query by hand did, cascading through all three tables. Strange, but at least I know my tables work correctly.

It is enough to have ON DELETE CASCADE option. Have a look at this example:

Create and fill tables:

CREATE TABLE molecule (
  id INT(11) NOT NULL,
  PRIMARY KEY (id)
)
ENGINE = INNODB;

CREATE TABLE descriptor (
  id INT(11) NOT NULL,
  molecule_id INT(11) DEFAULT NULL,
  PRIMARY KEY (id),
  CONSTRAINT FK_descriptor_molecule_id FOREIGN KEY (molecule_id)
    REFERENCES molecule(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;

CREATE TABLE tdepdescriptor (
  id INT(11) NOT NULL,
  descriptor_id INT(11) DEFAULT NULL,
  PRIMARY KEY (id),
  CONSTRAINT FK_tdepdescriptor_descriptor_id FOREIGN KEY (descriptor_id)
    REFERENCES descriptor(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;

INSERT INTO molecule VALUES 
  (1),
  (2),
  (3);

INSERT INTO descriptor VALUES 
  (1, 1),
  (2, 1),
  (3, 2);

INSERT INTO tdepdescriptor VALUES 
  (1, 1),
  (2, 2),
  (3, 3);

Delete one molecule and all its descriptor and all its tdepdescriptor:

DELETE FROM molecule WHERE id = 1;

SELECT * FROM molecule;
+----+
| id |
+----+
|  2 |
|  3 |
+----+

SELECT * FROM descriptor;
+----+-------------+
| id | molecule_id |
+----+-------------+
|  3 |           2 |
+----+-------------+

SELECT * FROM tdepdescriptor;
+----+---------------+
| id | descriptor_id |
+----+---------------+
|  3 |             3 |
+----+---------------+

Please make sure that you are using the Engine InnoDB in all the tables chained to wach other in foreign keys with on update/delete cascade, you may use:

create table test1 (
  #column definitions, including fk with on delete/update cascade
) engine = "InnoDB";

My exprience:

I had the same problem on one of my projects. An already developed database was given to me for adding some more parts. The tables did not have on delete/update cascade on foreign keys. I added them, also I added aother table from "query" tab in phpMyAdmin of cPanel. so I had a relation as:

(priorities) 1-m (packages) 1-m (standards)

All with on delete/update cascade. But when I used to delete "priority" , "standard" was not deleted. "priorities" and "packages" existed with "InnoDB" engine and when I created "standards" table, I did not specify the ENGINE, so it used "MyISAM" by default, that caused the problem. When I recreated the table with the ENGINE="InnoDB" explicitly mentioned, the problem was solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM