这个MYSQL查询如何更好
我有一个表,其中包含用户的所有照片。出于某种原因(不在乎为什么),可以从用户表中删除(使用DELETE FROM)某些用户,但照片保留在照片表中 我需要知道用户表中实际存在的用户照片数量 我提出的第一个解决方案是:这个MYSQL查询如何更好,mysql,Mysql,我有一个表,其中包含用户的所有照片。出于某种原因(不在乎为什么),可以从用户表中删除(使用DELETE FROM)某些用户,但照片保留在照片表中 我需要知道用户表中实际存在的用户照片数量 我提出的第一个解决方案是: SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users) 但我不确定做两个查询是否是最好的。有更好的方法吗?最好的方法是在两个表之间使用外键约束,并实现级联删除。MySQL手
SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users)
但我不确定做两个查询是否是最好的。有更好的方法吗?最好的方法是在两个表之间使用外键约束,并实现级联删除。MySQL手册中提供了更多信息:
正如评论人士指出的,这需要使用InnoDB存储引擎 首先,您的查询不会返回用户表中实际存在的用户添加的照片数,而是返回用户表中至少有一个匹配行的用户数 此查询应该是等效的(可能更好,但性能可能更差): 如果您确实需要用户表中用户添加的照片数量:
SELECT COUNT(*)
FROM photos, users
WHERE photos.user_id = users.id
假设您没有重复的用户ID。如果您想知道您有多少非孤立图片,您根本不需要
清晰的
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表。
您仍然可以进行级联删除
在前导表上的delete
触发器后放置一个,并按如下方式放入代码:
你可以吃你的蛋糕,也可以吃她
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\u id
,并删除那些链接到现在已删除的用户的 如果您添加需要InnoDB引擎的其他信息,这将是一件好事。我同意这里应该使用外键。但是由于某种原因,最初的那个人没有使用它们。count(*)
总是比count(一些字段)
快。
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 ;