Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个MYSQL查询如何更好_Mysql - Fatal编程技术网

这个MYSQL查询如何更好

这个MYSQL查询如何更好,mysql,Mysql,我有一个表,其中包含用户的所有照片。出于某种原因(不在乎为什么),可以从用户表中删除(使用DELETE FROM)某些用户,但照片保留在照片表中 我需要知道用户表中实际存在的用户照片数量 我提出的第一个解决方案是: SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users) 但我不确定做两个查询是否是最好的。有更好的方法吗?最好的方法是在两个表之间使用外键约束,并实现级联删除。MySQL手

我有一个表,其中包含用户的所有照片。出于某种原因(不在乎为什么),可以从用户表中删除(使用DELETE FROM)某些用户,但照片保留在照片表中

我需要知道用户表中实际存在的用户照片数量

我提出的第一个解决方案是:

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 ;