前面有两件事。首先,我有一个解决我的问题的方法。我在这里寻求指导,看看它是否是一个好的解决方案,以及我是否可以做得更好。其次,我想为我的无知道歉!我是一个 Java 人,正在建立一个刚刚进入 SQL 的站点。我还有很多学习要做,这就是我在这里寻求指导的原因。
我有三个处理这个查询的表。
- 用户 - 网站上所有用户的基本信息
- Friends - 保存两个朋友的用户 ID
- 大步 - 想想像 facebook 墙贴这样的大步。任何用户都可以在他们的墙上或朋友墙上发布步幅更新。
查找所有用户好友并返回其 ID 号的 SQL 语句如下所示。
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
现在我的目标是拥有一个像现场直播一样的Facebook。因此,任何时候用户发布一个跨步,他们的所有朋友都会被告知。所以我知道第一步是让所有用户成为朋友,就像我在上面所做的那样。所以现在我想将这些朋友链接到步幅表。
在步幅表中有 sourceUserId(编写步幅的人)和接收者Id(接收步幅的人)的列。因此,如果您在自己的板上写字并且您的 id 为 2,那么这两个列都是 2。我的目标是创建一个 SQL 语句,可以找到所有用户的朋友,以及这些朋友在他们的董事会和他们的朋友董事会上发表的所有帖子。
经过太多的谷歌搜索后,我发现了 SQL 子查询并得出了一个结果。问题是我是新手,不知道这是不是一个好结果,因为我今天才知道这些东西!我对可扩展性感到害怕,如果我拥有 100、1,000 甚至 100,000 个用户,这件事是否会变得混乱!所以我的问题是,
- 子查询是这里的最佳选择吗?如果是这样,我做对了吗?如果不是我该如何解决这个问题
- 是否有任何列我应该索引以加快此查询。
- 对于如何改进我未来的查询,您对新的 SQL 人员有什么其他建议吗?
这是我想出的代码!
SELECT * FROM stride WHERE sourceUserId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
AND recipientId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
更新:有了一堆新知识,我已经能够为我的实时提要获得一个可靠的 SQL 语句,即 0.0009 秒!这里适合任何有兴趣的人。
SELECT stride.id AS link, sourceUser.userName, sourceUser.displayName, recipientUser.fName AS recipient, sourceUser.currentDefault, stride.content, stride.timestamp,
CASE WHEN (recipientId = sourceUserId) THEN "personalStride" ELSE "friendStride" END AS notType
FROM stride
INNER JOIN user AS sourceUser ON sourceUser.id = stride.sourceUserId
INNER JOIN user AS recipientUser ON recipientUser.id = stride.recipientId
WHERE sourceUserId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
AND recipientId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
ORDER BY timestamp desc