我有下面的透视表 chat_user
将用户对象连接到聊天对象。
其行为是,任何数量的聊天可能存在,有2个或更多的参与者。我在这里说明了这个案例。我试图制定一个有效的查询,将用户id 16和用户id 29391作为输入,如果存在这样一个chat id,正好这两个用户id参与其中(本例中的chat id 1),则返回它以进行进一步处理。它应该忽略其他用户也参与的匹配,例如chat\u id 2。
由于系统的设计方式,此表可能达到n^2,其中n是用户数,而不考虑群聊。我需要一个能够在合理的syncron响应时间内处理这些数字(可能是数百万行)的查询,当我写出来的时候,这听起来越来越不可能了。
因此,我正在寻找一个mysql向导来告诉我这是否合理,甚至可能,或者我是否应该认真重新设计这种安排。我这样做是为了支持1对1聊天以及群聊天,同时保持完全的引用完整性。我也在尽可能地重用代码,因为这个聊天只是大型web应用程序的一个小组件。我真的是想避免做1对1和小组聊天作为不同的模式与单独的存储和所有,但如果这是疯狂的,那么我没有选择。我以前在使用sql向导时取得了很好的效果,所以我保持乐观。
另外,请进入至少适度的细节,我是相当新手,当谈到sql,所以我可能无法拼凑基本指令在一起。
热释光;dr:以两个用户id作为输入的查询,当且仅当正好有两行匹配给定的用户id和一些共同的聊天id时,才返回一个聊天id。这对一个可能是百万富翁的人来说太难了吗?
编辑::这是我目前的工作
SELECT u1.chat_id
FROM chat_user u1
INNER JOIN chat_user u2
ON u1.chat_id = u2.chat_id
WHERE (u1.user_id = ? AND u2.user_id = ? )
AND u1.chat_id IN (SELECT chat_id
FROM chat_user
GROUP BY chat_id
HAVING Count(chat_id) = 2)
复制粘贴表让任何有兴趣的人快速开始尝试
CREATE TABLE `chat_user` (
`chat_id` int(10) UNSIGNED NOT NULL,
`user_id` int(10) UNSIGNED NOT NULL,
`engaged` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `chat_user` (`chat_id`, `user_id`, `engaged`) VALUES
(1, 16, 1),
(1, 29391, 1),
(2, 16, 1),
(2, 555, 0),
(2, 29391, 1),
(3, 14, 0),
(3, 29391, 1);
ALTER TABLE `chat_user` ADD PRIMARY KEY (`chat_id`,`user_id`);
1条答案
按热度按时间axkjgtzd1#
以下是我的方法:
你需要索引
(user_id, chat_id)
继续(chat_id, user_id)
. 您定义的主键对于后一个索引就足够了。