从多个表中删除多行

时间:2012-12-23 02:44:35

标签: mysql sql

我有三张桌子:

`MEMBERS`
with
`NAME` varchar(24) UNIQUE KEY

`LAST_LOGGED_IN` int(11) - It is a timestamp!

`HOMES`
with
`OWNER` varchar(24) 

`CARS`
with
`OWNER` varchar(24)

我对这些表使用InnoDB,现在我的实际问题是:如果UNIX_TIMESTAMP() - MEMBERSLAST_LOGGED_IN>如何删除所有表中的行? 864000吗

我正在尝试删除非活动成员的行,这是最难的事情。我有大约40K行,并且增加了。我用DELETE FROM MEMBERS WHERE UNIX_TIMESTAMP()-LAST_LOGGED_IN> 864000

定期清理它

您的任何帮助都将非常感激!谢谢!

2 个答案:

答案 0 :(得分:1)

我不使用InnoDB所以我不得不查找它,但它似乎确实支持参考完整性。如果您设置关系然后打开ON DELETE CASCADE,数据库本身将强制执行规则...即,当您删除成员时,DBMS将负责删除关联的Homes和Cars。

请参阅herehere,他们可能会有帮助。

答案 1 :(得分:1)

如果您已从MEMBERS表中删除了行,并且希望从其他两个表中删除OWNER列的值与NAME不匹配的行MEMBERS表中任何行的值:

DELETE h.*
  FROM `HOMES` h
  LEFT
  JOIN `MEMBERS` m 
    ON m.`NAME` = h.`OWNER`
 WHERE m.`NAME` IS NULL

DELETE c.*
  FROM `CARS` c
  LEFT
  JOIN `MEMBERS` m 
    ON m.`NAME` = c.`OWNER`
 WHERE m.`NAME` IS NULL

(N.B。这些语句还会将HOMESCARS列中的行作为NULL值从OWNER列中删除。)

我强烈建议您在运行DELETE之前使用SELECT运行这些语句的测试。 (将关键字DELETE替换为关键字SELECT,即

-- DELETE h.*
SELECT h.*
  FROM `HOMES` h
  LEFT
  JOIN `MEMBERS` m 
    ON m.`NAME` = h.`OWNER`
 WHERE m.`NAME` IS NULL

接下来,如果要保持这些表“同步”,可以考虑使用ON CASCADE DELETE选项定义FOREIGN KEY约束。

或者,您可以使用DELETE语句删除所有三个表中的行:

DELETE m.*, h.*, c.*
  FROM `MEMBERS` m
  LEFT
  JOIN `HOMES` h
    ON h.`OWNER` = m.`NAME`
  LEFT
  JOIN `CARS` c
    ON c.`OWNER` = m.`NAME`
 WHERE UNIX_TIMESTAMP()-m.`LAST_LOGGED_IN` > 864000

(N.B。谓词不能在LAST_LOGGED_IN列上使用索引。引用“bare”列的等效谓词将能够使用索引。

WHERE m.`LAST_LOGGED_IN` < UNIX_TIMESTAMP()-864000

或同等的:

WHERE m.`LAST_LOGGED_IN` < UNIX_TIMESTAMP(NOW() - INTERVAL 10 DAY)

为了获得最佳性能,您需要HOMESCARS上的索引,其前导列为OWNER,例如

... ON `HOMES` (`OWNER`)
... ON `CARS` (`OWNER`)