假设我的数据库中有5个MyISAM表。每个表都有一个键,我们称之为“id_num”......
“id_num”是我用来将所有表连接在一起的字段。某个值“id_num”可能出现在所有表中,有时也只出现在表的一个子集中。
如果我想删除数据库中某个“id_num”的所有实例,我是否可以在所有表上执行DELETE命令,还是应该检查“id_num”的值是否存在?
DELETE * FROM table1 WHERE id_num = 123;
DELETE * FROM table2 WHERE id_num = 123;
DELETE * FROM table3 WHERE id_num = 123;
DELETE * FROM table4 WHERE id_num = 123;
DELETE * FROM table5 WHERE id_num = 123;
或者我应该先在每个表上执行SELECT命令,以检查删除前表中是否存在这些行?什么是最佳做法?
(我正在使用MyISAM,所以这里不能选择级联删除。)
答案 0 :(得分:1)
听起来你需要按照以下方式更改设计 - 将id_num
表作为PK,并在其他表中使id_num
成为FK,并使用on-delete-cascade。这将允许您只运行一个删除语句来删除所有适用的数据(这通常也是更正确的处理方式)。
以上显然在MyISAM中不起作用,但有a workaround using triggers(但现在看起来似乎不太吸引人)。
但我相信您的上述查询应该有效,无需先检查某些内容是否存在,DELETE
将无法执行任何操作。
如果您想查看数据是否实际被删除,大多数API会为您提供某种rows affected
计数。
答案 1 :(得分:0)
在从表中删除之前,不应执行select查询。因为select查询会给服务器带来一些额外的负担。但是,执行删除查询后,您可以使用php中的mysql_affected_rows()函数检查已删除的行数。
答案 2 :(得分:0)
要回答有关首次运行SELECT的问题,这样做没有任何好处。如果给定表中没有行,则DELETE将仅影响零行。如果有匹配的行,那么首先执行SELECT,然后执行DELETE,只需要完成查找行的两倍。所以只需执行DELETE即可完成。
您是否知道MySQL具有多表DELETE语法?
如果您确定table1具有匹配的行,则可以对其他行使用外部联接:
DELETE table1.*, table2.*, table3.*, table4.*, table5.*
FROM table1
LEFT OUTER JOIN table2 USING (id_num)
LEFT OUTER JOIN table3 USING (id_num)
LEFT OUTER JOIN table4 USING (id_num)
LEFT OUTER JOIN table5 USING (id_num)
WHERE table1.idnum = 123;
我假设在所有这些表中索引id_num,否则执行JOIN将表现不佳。但是,在没有索引的帮助下执行DELETE来查找行也会表现不佳。