【发布时间】:2022-01-19 07:22:54
【问题描述】:
我正在尝试构建一个类似于 slack chat 的聊天应用程序,我想了解他们是如何设计他们的数据库的,当有人加载聊天时它会立即返回这么多信息,哪个数据库适合这个问题,我是添加相同的屏幕截图以供参考。
最初,当我开始考虑这个问题时,我想继续使用 PostgreSQL,并始终保持表规范化以保持其干净,但随着我继续进行规范化,我开始觉得这是一个问题。
用户表
| id | name | |
|---|---|---|
| 1 | John | john@gmail.com |
| 2 | same | sam@gmail.com |
频道表
| id | channel_name |
|---|---|
| 1 | Channel name 1 |
| 2 | Channel name 2 |
参与者表
| id | user_id | channel_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
聊天表
| id | user_id | channel_id | parent_id | message_text | total_replies | timestamp |
|---|---|---|---|---|---|---|
| 1 | 1 | 1 | null | first message | 0 | - |
| 2 | 1 | 2 | 1 | second message | 10 | - |
| 3 | 1 | 3 | null | third message | 0 | - |
聊天表的列名 parent_id 告诉它是父消息还是子消息我不想使用递归子消息,所以这很好
表情符号表
| id | user_id | message_id | emoji_uni-code |
|---|---|---|---|
| 1 | 1 | 12 | U123 |
| 2 | 1 | 12 | U234 |
| 3 | 2 | 14 | U456 |
| 4 | 2 | 14 | U7878 |
| 5 | 3 | 14 | U678 |
一个人可以对同一条消息使用多个表情符号做出反应
当有人加载时,我想获取插入到表中的最后 10 条消息 所有已对每条消息和回复做出反应的表情符号,就像您在图像中看到的那样,上面写着 1 条回复与人的个人资料图片(这可以超过 1 条)
现在要获取这些数据,我必须加入所有表,然后获取数据,这在后端可能是一项非常繁重的工作,考虑到这将非常频繁。
我想我会在 Chat 表中再添加两列,它们是 profile_replies 和 emoji_reactions_count,它们都是 bson 数据类型来存储类似这样的数据
这用于 emoji_reactions_count 列
这也有两种方式,一种是计数方式
{
"U123": "123",// count of reactions on an emoji
"U234": "12"
}
当有人做出反应时,我会更新计数并从表情符号表中插入或删除行,在这里我有一个问题,任何消息的表情符号更新过于频繁可能会变慢?因为每次有人对表情符号做出反应时,我都需要更新上表中的计数
或
像这样存储用户 ID 和计数,这样看起来更好,我可以完全摆脱 Emojis 表
{
"U123": {
"count": 123, // count of reactions on an emoji
"userIds": [1,2,3,4], // list of users ids who all have reacted
},
"U234": {
"count": 12,
"userIds": [1,2,3,4],
},
}
这用于 profile_replies 列
[
{
"name": 'john',
"profile_image": 'image url',
"replied_on": timestamp
},
... with similar other objects
]
这看起来不错的解决方案还是我可以做些什么来改进或者我应该切换到一些 noSQL 数据库,如 mongodb 或 cassandra?我考虑过 mongodb,但这看起来也不是很好,因为当数据呈指数增长时连接速度很慢,但相对而言,这在 sql 中不会发生。
【问题讨论】:
-
尝试向开源学习:google.com/search?q=instant+chat+site%3Agithub.com。 “表情符号表”似乎有点矫枉过正。 Postgres 可以很好地处理 JSON 数据,只需将 emoji JSON 列添加到“聊天表”即可。 “最近 10 条消息”有点模糊,你如何处理最近对 2 个月大的消息的回复?如果它是一个宠物项目 - 根据需要尝试和重构。你会从自己的错误中学到比别人宣称的最佳实践更多的东西。特别是如果您在某个时候更改数据库引擎。
-
您能解释一下您预期的瓶颈吗?例如,您希望哪张桌子最大,它必须承受多少记录?如果您正在考虑为最多 10K 活跃用户的应用程序,答案可能非常明显。
标签: sql database mongodb postgresql cassandra