我有一張表格,裏面包含了用戶的所有照片。出於某種原因(不在乎爲什麼),某些用戶可以從用戶表中刪除(使用DELETE FROM),但照片保留在照片表中。這個MYSQL查詢如何更好
我需要知道用戶表中實際存在的用戶數量。
我想出了第一個解決方案是這樣的:
SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users)
但我不知道,如果做兩個查詢是最好的一個。有一個更好的方法嗎?
我有一張表格,裏面包含了用戶的所有照片。出於某種原因(不在乎爲什麼),某些用戶可以從用戶表中刪除(使用DELETE FROM),但照片保留在照片表中。這個MYSQL查詢如何更好
我需要知道用戶表中實際存在的用戶數量。
我想出了第一個解決方案是這樣的:
SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users)
但我不知道,如果做兩個查詢是最好的一個。有一個更好的方法嗎?
這樣做的最好方法是在兩個表之間使用foriegn鍵約束,並實現級聯刪除。提供更多信息在MySQL手冊:
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
正如評論者所指出的那樣,這需要使用InnoDB存儲引擎。 This is the default storage engine as of MySQL 5.5.5.
首先,你的查詢會不返回由用戶添加的照片中實際存在的用戶表中的號碼 - 而是返回其在至少一個匹配行從用戶表的用戶數照片表。
這個查詢應該是等價的(可能會更好,可能是性能方面更差雖然):
SELECT COUNT(DISTINCT user_id)
FROM photos, users
WHERE photos.user_id = users.id
如果你真的需要存在於用戶表的用戶添加的照片數量:
SELECT COUNT(*)
FROM photos, users
WHERE photos.user_id = users.id
假設您沒有重複的用戶標識符。
'count(*)'總是比'count(some_field)'更快。 – Johan 2011-06-01 20:36:11
如果你想知道你有多少個非孤兒圖片,你完全不需要DISTINCT
。
SELECT COUNT(*)
FROM users u
INNER JOIN photos p ON (p.user_id = p.id)
使用此sql查詢。
SELECT COUNT(*)
FROM photos p
INNER JOIN users u
ON p.user_id = u.user_id
級聯刪除的MyISAM
爲了擴大對AJ的答案。如果你不想改變表格。或者你沒有InnoDB表。
您仍然可以級聯刪除。
放在主導表after delete
觸發,並把代碼是這樣的:
您可以有Y'R魚和熊掌兼得她太
DELIMITER $$
CREATE TRIGGER ad_users_each AFTER DELETE ON users FOR EACH ROW
BEGIN
DELETE FROM photos WHERE photos.user_id = old.id;
END $$
DELIMITER ;
瞧,在級聯刪除MyISAM數據。
它是如何工作的?
觸發後每個成功刪除表用戶中的一行。
觸發器中的old
虛擬表在其被刪除之前的值爲users.id
。我使用該ID來查找表photos
中的所有匹配的user_id
,並刪除那些已鏈接到現在已刪除的用戶的鏈接。
如果您添加需要InnoDB引擎的其他信息,那將會很好。 – RRStoyanov 2011-06-01 20:03:39
我同意在這裏使用foreigns鍵。但由於某種原因,原來這樣做的人並沒有使用它們。 – aseba 2011-06-01 20:03:58
@aseba比你做;) – RRStoyanov 2011-06-01 20:05:29