繁体   English   中英

选择确切用户之间的对话(通过用户ID)

[英]Select a conversation between exact users (by users IDs)

我正在使用一个简单的聊天应用程序。 它应该允许用户在用户之间或组(多个用户)中运行对话。 所以这是我的桌子:

table users
ID   | username      | ...

table conversations
ID   | ...

table conversations_users
ID   | user_id       | conversation_id

假设我选择了几个用户(ids 11、22和33)并希望检查数据库中是否已经存在这些确切用户 (两个,三个或更多)之间的对话。 我可以通过多个查询和一些后端操作来实现这一点,但是我敢肯定这会对性能产生很大影响。

一个查询甚至可能吗?


附带的问题:如果有一个简单的解决方案,它对于真正的长表(例如1.000.000对话,conversations_users中的〜3.000.000行)和多用户查询( 仍然检查是否存在100个用户之间的对话)仍然有效 )?

当你说:

这些确切用户之间的对话...

我低估了,您在对话中只希望这些用户,而没有其他人。
在这种情况下,很简单:

sum(case when user_id in (11, 22, 33) then 1 else 0 end) = 3

不会给出正确的结果,因为它将返回这3个用户参与但可能与其他用户一起参与的所有conversation_id
您需要与count(*)进行比较:

select conversation_id
from conversation_users
group by conversation_id
having sum(user_id in (11, 22, 33)) = count(*);

我相信,有没有重复user_id S对于每个conversation_id ,所以没有必要count(distinct user_id)
对于这3个用户之间以及其他用户之间的对话,可以使用where子句:

select conversation_id
from conversation_users
where user_id in (11, 22, 33)
group by conversation_id
having count(*) = 3;

一种方法是聚合:

select cu.conversation_id
from conversation_users cu
group by cu.conversation_id
having sum(case when cu.user_id in (11, 22, 33) then 1 else 0 end) = 3;

从性能角度来看,这样做可能会更快:

select c.*
from conversations c
where exists (select 1
                  from conversation_users cu
                  where cu.conversation_id = c.id and
                        cu.user_id = 11
                 ) and
     exists (select 1
                  from conversation_users cu
                  where cu.conversation_id = c.id and
                        cu.user_id = 22
                 ) and
     exists (select 1
                  from conversation_users cu
                  where cu.conversation_id = c.id and
                        cu.user_id = 33
                 ) and
           not exists (select 1
                  from conversation_users cu
                  where cu.conversation_id = c.id and
                        cu.user_id not in (11, 22, 33)
                 ) ;

这可以利用conversation_users(user_id)上的索引。

与任何性能问题一样,您需要对数据库和数据进行测试。 无论用户数量如何,第一个查询的性能都非常稳定。 随着用户数量的增加,第二个将下降。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM