我正在编写一个具有聊天功能并使用Postgres作为数据库的应用程序。涉及4个表 - 用户(保存用户数据,包括其ID),组(保存组列表,包括groupid),group_users(保存groupid到userid的映射,1到多个)和groupchats(保存映射) groupid到进入聊天的用户ID和文本本身)。所有表都有明显的外键。
我想获取属于给定groupid的groupchats中的所有行。但是,如果请求它的人在该组中,我只希望这样做。我还希望获得每一行的人的名字(请记住该行存储用户ID)。
以下是我的想法。我很好奇的是,如果有更好的方法吗?我正在使用子查询来获取当前行中用户的名称。我应该使用加入吗?另外,我相信我的第二个子查询(对于exists子句)应该只运行一次,我是否正确?或者我会在客户端逻辑中做得更好(对数据库进行第二次往返)?我想exxt DB可以优化这个。
SELECT userid, chat, time,
(SELECT firstname FROM users WHERE id=groupchat.userid)
FROM groupchat
WHERE groupid=$1
AND EXISTS (SELECT userid
from group_users
WHERE groupid=$1 AND userid=$2)
ORDER BY time ASC;
答案 0 :(得分:2)
你的方法很好。您可以将其写为明确的JOIN
。使用关联还意味着您只需在查询中包含$1
一次:
SELECT gc.userid, gc.chat, gc.time, u.firstname
FROM groupchat gc JOIN
users u
ON u.id = gc.userid
WHERE gc.groupid = $1 AND
EXISTS (SELECT 1
FROM group_users fu
WHERE gu.groupid = gc.groupid AND gu.userid = $2
)
ORDER BY gc.time ASC;
如果您有大量数据,那么您需要以下索引:groupchat(groupid, time)
,users(id, firstname)
和group_users(groupid, userid)
。