I have three tables in MySQL v5.6 created by:
CREATE TABLE tm ( id INT AUTO_INCREMENT, PRIMARY KEY (id) ); CREATE TABLE th ( id INT AUTO_INCREMENT, PRIMARY KEY (id) ); CREATE TABLE tr ( id INT AUTO_INCREMENT, tm_id INT, th_id INT, PRIMARY KEY (id), CONSTRAINT fk_1 FOREIGN KEY (tm_id) REFERENCES tm (id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_2 FOREIGN KEY (th_id) REFERENCES th (id) ON DELETE CASCADE ON UPDATE CASCADE ); INSERT INTO tm (id) VALUES (101); INSERT INTO tm (id) VALUES (102); INSERT INTO th (id) VALUES (1); INSERT INTO tr (tm_id, th_id) VALUES (101,1), (102,1);
So in the end I have three tables with following data:
th | id | |----| | 1 | tr | id | tm_id | th_id | |-----|---------|-------| | 11 | 101 | 1 | | 12 | 102 | 1 | tm | id | |------| | 101 | | 102 |
And what I am trying to do is to delete all of them with one SQL query:
DELETE th, tr, tm FROM th LEFT JOIN tr ON tr.th_id = th.id LEFT JOIN tm ON tr.tm_id = tm.id WHERE th.id = 1;
As a result th
and tr
tables will be blank but tm will be left with id=102
+------+ | id | +------+ | 102 | +------+
And I am not searching for better query but trying to understand why tm.id=101 was deleted but tm.id=102 was left in the table?
Advertisement
Answer
This is the result of the InnoDB
storage engine which is used (as default) to create the tables and the foreign key constraints.
Check the demo without foreign keys and the result is that all rows of all tables are deleted.
You would get the same result, even with the foreign key constraints if you created the tables with the MyISAM
storage engine.
Check the demo.
But for the InnoDB
storage engine and the foreign key constraints, as it is mentioned in 13.2.2 DELETE Statement:
If you use a multiple-table DELETE statement involving InnoDB tables for which there are foreign key constraints, the MySQL optimizer might process tables in an order that differs from that of their parent/child relationship. In this case, the statement fails and rolls back. Instead, you should delete from a single table and rely on the ON DELETE capabilities that InnoDB provides to cause the other tables to be modified accordingly.
so what you get may be the result of a rollback for the deletion of id = 102
of tm
, because the order of the tables processed is such that it would violate a foreign key constraint.
Check the demo.