在MyISAM中删除之前,我应该检查表之间是否存在行?

时间:2013-02-15 06:05:21

标签: mysql

假设我的数据库中有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,所以这里不能选择级联删除。)

3 个答案:

答案 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来查找行也会表现不佳。