SQL-聊天数据库架构以删除一侧或双方的对话

wil*_*lpr 7 sql chat

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

  • 仅私人消息,从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 |
+-----------------------------------------+

*/
Run Code Online (Sandbox Code Playgroud)

通过这种方式。我可以为每个用户分开完整的聊天记录,然后按要求的参与者进行过滤。

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

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

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
Run Code Online (Sandbox Code Playgroud)

并将消息从用户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
Run Code Online (Sandbox Code Playgroud)

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

首先,检查用户B是否尚未删除其对话。如果已删除,则消息将从消息表中删除。否则,不会。

DELETE FROM conversation_table WHERE user_id=A AND participant_id=B
Run Code Online (Sandbox Code Playgroud)

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

邮件表将具有以下元数据:

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

好吧,一切都在这里工作,但是现在有一些问题:

  • 提出的设计是否可以处理成千上万的用户?我的意思是,为每个用户存储其传入和传出的消息。
  • 邮件ID呢?我在考虑32个字符的UUID。这个是可以建议的?(推荐的)。我的意思是,如果消息仅包含带有“ hello”的正文,则将需要32个字符的唯一ID,并且我认为这是不必要的吗?
  • 您可以帮助我指导我进行此设计吗?

谢谢。

小智 0

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

案例示例:

UserID: 1000001
MessageId: 1000001
Message: 'Hello'

UserID: 1000002
MessageId: 1000001
Message: 'Hi'
Run Code Online (Sandbox Code Playgroud)

让我知道你的想法!!