【问题标题】:SQL - Chat database schema to delete conversation for one side or bothSQL - 聊天数据库模式以删除一侧或两侧的对话
【发布时间】:2016-04-21 19:05:12
【问题描述】:

我正在设计一个具有以下要求的聊天数据库:

  • 只有私人消息,A 到 B。没有群组或房间。
  • 当用户 A 向 B 发送消息时,如果用户 A 删除对话,用户 B 仍然可以查看该对话,直到用户 B 删除它。
  • 消息不能单独删除。只能删除完整的历史对话。

现在我有了这个:

  • 当用户 A 向用户 B 发送消息时,将创建一个带有 id 的消息寄存器。这将是对话表的外键。
  • 在会话表中,将为相同的消息 ID 创建两个寄存器。一个用于发送消息的用户,另一个用于接收消息的用户。每个寄存器都有一个名为 in-out 的字段,用于指定消息是发送还是接收。示例:

/*
conversation_table                              messages_table
+--------------------------------------------+  +----------------------------------------+
| user_id | participant_id | in-out | msg_id |  | msg_id |            body               |
+--------------------------------------------+  +----------------------------------------+
|    A    |        B       |    0   |   101  |  |   101  | Hello B, what's up            |
|    B    |        A       |    1   |   101  |  |   102  | Hey A, here in stackoverflow  |
|    B    |        A       |    0   |   102  |  |   103  | That's nice B, and what's new |
|    A    |        B       |    1   |   102  |  +----------------------------------------+
|    A    |        B       |    0   |   103  |
|    B    |        A       |    1   |   103  |
+--------------------------------------------+


Chat windows

+-----------------------------------------+
| User A                                  |
+-----------------------------------------+
| Sent: Hello B, what's up                |
| Received: Hey A, here in stackoverflow  |
| Sent: That's nice B, and what's new     |
+-----------------------------------------+

+-----------------------------------------+
| User B                                  |
+-----------------------------------------+
| Received: Hello B, what's up            |
| Sent: Hey A, here in stackoverflow      |
| Received: That's nice B, and what's new |
+-----------------------------------------+

*/

这样。我可以为每个单独的用户分离他们的完整聊天历史记录,然后用所需的参与者进行过滤。

只需使用 in-out var,就可以轻松地将发送消息与接收消息分开。例如,如果收到消息 (0) 将其放在左侧,或者如果已发送消息,则将其放在右侧。

获取用户 A 与用户 B 聊天的消息的 SQL:

SELECT * FROM conversation_table C INNER JOIN messages_table M ON (C.msg_id=M.msg_id)   WHERE C.user_id=A AND C.participant=B

然后将用户 A 的消息插入用户 B:

INSERT INTO messages_table (msg_id, body) VALUES (101, 'Hello B, what's up')

INSERT INTO conversation_table (user_id, participant_id, in-out, msg_id) VALUES 
(A, B, 0, 101) #messages get out from user A to User B
(B, A, 1, 101) #message comes in to user B from user A

删除用户A的消息历史,与用户B聊天:

首先,检查用户 B 是否没有删除他们的对话。如果已删除,则消息将从消息表中删除。否则,不。

DELETE FROM conversation_table WHERE user_id=A AND participant_id=B

这将删除用户 A 帐户中用户 A 和 B 之间的完整对话。用户 B 拥有自己的消息副本。

Messages 表将包含如下元数据:

  • 时间戳(UTC 当前毫秒)获取日期时间和可视化顺序

好吧,这里一切正常,但现在有一些问题:

  • 所呈现的设计是处理成千上万用户的好模型吗?我的意思是,为每个用户存储他们传入和传出的消息。
  • 消息 ID 怎么样。我正在考虑使用 32 个字符的 UUID。这个是可以建议的? (推荐的)。我的意思是,如果消息只包含一个带有“hello”的正文,则需要一个 32 字符的唯一 ID,我认为这将是不必要的,或者不是?
  • 您能帮我指导一下这个设计吗?

谢谢。

【问题讨论】:

  • 有点晚了 :D 但是,如何为 mongodb 数据库创建这个?我发现很难删除一个用户的对话:)

标签: sql chat


【解决方案1】:

考虑到您正在使用 mysql 顺序自动增量主键作为 ids

创建一个被 1 删除并被 2 删除的列(被一个用户 1 删除,用户 1 的用户 ID 号较小,2 号较大)。

然后在获取消息时,仅根据用户列值(即上次删除的消息 ID)获取该用户删除后的消息。

您也可以使用时间戳来存储删除点,但这会产生时区问题,并且 mysql、django、laravel 或 express 等不同的框架都有自己的日期时间问题。

【讨论】:

    【解决方案2】:

    此数据模型应该适合您的任务。对于会话应设置“级联删除”。

    从 DeleteFrom=1 和 DeleteTo=1 的会话中删除

    它将删除两个用户删除的所有会话和消息。当用户删除会话 SET DeleteFrom/To = 1.

    Id 是 IDENTITY = 自动增量。 Order By Id 提供消息的顺序。

    如果消息来自 UserIdFrom,则添加“From BIT” = 1,如果 - 来自 UserIdTo,则 = 0。

    【讨论】:

      【解决方案3】:

      我不建议使用UUIDNEWID()(在SQL Server 中使用)来存储每条消息,正如您之前建议的那样,将为每条消息生成32 个字符的ID。例如,如果您有 1000 个用户,并且每个用户每天发送大约 10 条消息,则生成的 UID 总数将为 10000,现在您可以计算每周、每月和每年的数学。实际上它将有更多的数据,所以我建议您使用两个值的组合作为唯一标识符。 UserIDMessageID。 将它们标记为 15 位数值或任何您认为正确的值,然后将它们组合起来以识别每个用户的消息。

      示例案例:

      UserID: 1000001
      MessageId: 1000001
      Message: 'Hello'
      
      UserID: 1000002
      MessageId: 1000001
      Message: 'Hi'
      

      告诉我你的想法!!

      【讨论】:

        【解决方案4】:

        我认为在关系数据库中很好。大多数人都遵循类似的架构

        【讨论】:

        • 这应该是评论而不是答案
        猜你喜欢
        • 2021-02-04
        • 1970-01-01
        • 2011-03-06
        • 2018-05-29
        • 2012-06-17
        • 1970-01-01
        • 2015-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多