2012-12-23 63 views
2

我有三個表:刪除多個表中的多行

`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() -如何刪除所有表中的行。 LAST_LOGGED_IN> 864000?

我試圖刪除非活動成員的行,這是最難的事情。我有大約40K行,並且增加。我經常清理它DELETE FROM MEMBERS WHERE UNIX_TIMESTAMP()-LAST_LOGGED_IN> 864000

你的任何幫助將非常感激!謝謝!!

+0

好的第一個問題。 – slm

回答

1

如果您已經從MEMBERS表中刪除行,你想從其他兩個表中刪除的行,其中OWNER列的值不會在MEMBERS表中任何行匹配NAME值:

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 

(NB這些語句也將從HOMESCARS表中刪除行OWNER列作爲NULL值。)

我強烈建議你運行一個TE在運行DELETE之前,使用SELECT使用這些語句的st。 (替換關鍵字用關鍵字選擇刪除,即

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

展望未來,如果你想「同步」,以保持這些表,你可以考慮定義外鍵約束與ON CASCADE DELETE選項。

或者,您可以使用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 

(NB謂詞出現無法使上使用索引3210欄。引用「裸」列的等價謂詞將能夠使用索引。

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`) 
+0

非常詳細,謝謝。 – Lorenc

1

我不使用InnoDB,因此我不得不查看它,但確實看起來支持參照完整性。如果您設置關係,然後打開ON DELETE CASCADE,則數據庫本身將執行規則......即,當您刪除成員時,DBMS將負責刪除關聯的Homes和Cars。

請參閱herehere,它們可能會有所幫助。

+0

在HOMES和CARS中可能存在「孤立」行(假設OP已經在MEMBERS表上運行刪除操作)。爲了定義外鍵約束(對於InnoDB),子表中現有的「孤立」行(通過以前的父刪除而成爲孤兒)將需要刪除,或者將member_id列設置爲NULL。 – spencer7593