我在我的架构中做错了什么吗?
Am I doing something wrong in my schema?
我设计了一个数据库模式,允许 Facebook 风格的消息传递系统(没有能够编辑消息的功能)。这是:
我的想法是用户向对话发送消息,而不是向其他用户发送消息。通过这种方式,用户可以订阅对话,从而允许多用户聊天。
一个conversation
就像一个房间。如果用户 bob 和用户 joe 开始交谈,如果对话不存在,将创建一个对话。每当 'bob' 和 'joe' 交谈时,他们的信息总是相同的 conversation_id
。这将允许我通过 conversation_id
.
获取所有消息来 return 他们的所有通信
多个用户可以成为一个 conversation
的一部分。 conversation_users
table 存储 conversation_id
和 user_id
,这允许我查询 table 以获得 All users who have the conversation_id X
.
我遇到的问题是我想查询:Give me the conversation_id used by Joe and Bob
,所以我可以使用这个 conversation_id
到 return 'Joe' 之间的所有消息和 'Bob'.
我怎样才能做到这一点?我想我从我的模型中遗漏了一些重要的东西,这使得它看起来比它需要的更复杂。但是我看不到什么。
您需要 Joe 和 Bob 使用的 conversation_id 值的交集。
如何获得 Joe 使用的 conversation_id 值?
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
你对 Bob 做同样的事情,给你两个子查询。验证这些;确保它们正常工作。
然后你这样做:
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
AND cu.conversation_id IN
(
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Bob'
)
这将为您提供涉及这两个用户的对话 ID 列表。 编辑一个JOIN
也可以处理这个逻辑,像这样。
SELECT a.conversation_id
FROM (SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
AND cu.conversation_id
) a
JOIN ( SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Bob'
) b ON a.conversation_id = b.conversation_id
第一个查询可以放在 MySQL 视图中,而第二个不能。哪个更快?不尝试两者很难知道。
这样的对话可能不止一次。如果您只想要一个,则必须弄清楚如何 select 它。
您的模型中没有遗漏任何东西。只是这种交集操作的逻辑有点微妙,因为 MySQL 没有 INTERSECTION
运算符。
我设计了一个数据库模式,允许 Facebook 风格的消息传递系统(没有能够编辑消息的功能)。这是:
我的想法是用户向对话发送消息,而不是向其他用户发送消息。通过这种方式,用户可以订阅对话,从而允许多用户聊天。
一个conversation
就像一个房间。如果用户 bob 和用户 joe 开始交谈,如果对话不存在,将创建一个对话。每当 'bob' 和 'joe' 交谈时,他们的信息总是相同的 conversation_id
。这将允许我通过 conversation_id
.
多个用户可以成为一个 conversation
的一部分。 conversation_users
table 存储 conversation_id
和 user_id
,这允许我查询 table 以获得 All users who have the conversation_id X
.
我遇到的问题是我想查询:Give me the conversation_id used by Joe and Bob
,所以我可以使用这个 conversation_id
到 return 'Joe' 之间的所有消息和 'Bob'.
我怎样才能做到这一点?我想我从我的模型中遗漏了一些重要的东西,这使得它看起来比它需要的更复杂。但是我看不到什么。
您需要 Joe 和 Bob 使用的 conversation_id 值的交集。
如何获得 Joe 使用的 conversation_id 值?
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
你对 Bob 做同样的事情,给你两个子查询。验证这些;确保它们正常工作。
然后你这样做:
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
AND cu.conversation_id IN
(
SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Bob'
)
这将为您提供涉及这两个用户的对话 ID 列表。 编辑一个JOIN
也可以处理这个逻辑,像这样。
SELECT a.conversation_id
FROM (SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Joe'
AND cu.conversation_id
) a
JOIN ( SELECT cu.conversation_id
FROM Users u
JOIN Conversation_Users cu ON u.id = c.user_id
WHERE username = 'Bob'
) b ON a.conversation_id = b.conversation_id
第一个查询可以放在 MySQL 视图中,而第二个不能。哪个更快?不尝试两者很难知道。
这样的对话可能不止一次。如果您只想要一个,则必须弄清楚如何 select 它。
您的模型中没有遗漏任何东西。只是这种交集操作的逻辑有点微妙,因为 MySQL 没有 INTERSECTION
运算符。