1

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

4

3 回答 3

1

要回答您关于首次运行 SELECT 的问题,这样做没有任何好处。如果给定表中没有行,则 DELETE 只会影响零行。如果有匹配的行,那么先执行 SELECT 再执行 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 将表现不佳。但是在没有索引帮助的情况下执行删除来查找行也会表现不佳。

于 2013-02-15T07:13:53.680 回答
1

听起来您需要按如下方式更改您的设计 - 有一个id_num作为 PKid_num的表,并在其他表中创建一个 FK,并带有 on-delete-cascade。这将允许您只运行一个删除语句来删除所有适用的数据(这通常也是更正确的处理方式)。

以上显然在 MyISAM 中不起作用,但是有一个使用触发器的解决方法(但现在它看起来确实是一个不那么吸引人的选项)。

但是我相信您的上述查询应该可以工作,无需先检查是否存在某些内容,DELETE而不会做任何事情。

rows affected如果您想查看数据是否实际被删除,大多数 API 都会为您提供某种计数。

于 2013-02-15T06:09:56.910 回答
0

在从表中删除之前,您不应该执行选择查询。因为选择查询会给服务器带来一些额外的负载。但是,在执行删除查询后,您可以使用 php.ini 中的 mysql_affected_rows() 函数检查已删除的行数。

于 2013-02-15T07:09:47.193 回答