【问题标题】:PostgreSQL: Database structure for Chat ConversationPostgreSQL:聊天对话的数据库结构
【发布时间】:2018-10-05 09:20:37
【问题描述】:

我正在设计一个用于聊天对话的表格。而不是创建 2 个表:对话和消息。我只设计了一张表:对话并使用JSONB 字段作为消息。

你们看看这张照片:

这个数据库结构解决方案是好是坏?如果它不好,我还有其他解决方案吗?

【问题讨论】:

    标签: database postgresql database-design


    【解决方案1】:

    我强烈建议您规范化您的表结构。

    参与者应进入包含id_conversationid_user 列的单独表格。搜索和更新比使用(json)数组更好。

    messages 相同。为什么不将它们存储到带有id_conversationtimestampid_usermessage_text 列的单独表中?它也可以更好地用于搜索和更新。它使您的对话表变得更小。


    另外participants 列的用途是什么?如果您有每个对话的消息,您可以轻松地向表格询问所有向对话提交消息的用户,例如

    SELECT DISTINCT id_user FROM messages WHERE id_conversation = 42
    

    编辑

    原则上:100 万个数据集很多,但不是一张巨大的表。具有良好表设计的 Postgres 应该不会有任何问题。但我假设一个对话包含的消息要少得多,因此您可以在过滤和索引方面做很多事情。

    1。 我强烈建议您为您的表格考虑一些巧妙的索引,这样可以使搜索变得非常快。也许消息时间戳上的索引可能会有所帮助,而转换 ID 上的索引可能会有所帮助:

    CREATE INDEX idx_messages_timestamp
    ON messages (timestamp);
    
    CREATE INDEX idx_messages_conversations
    ON messages (id_conversation);
    

    如果您想获取较新的消息,使用 DESC 顺序 (... ON messages(... DESC)) 创建索引可能会有所帮助

    2。 对于非常大的表(我的意思是非常大的表),partition 它可能会有所帮助。这会根据某个标准在内部拆分您的表格 - 可能是时间戳(例如每月或每年)。因此,如果您主要获取一些较新的数据,则较旧的数据将在内部存档在单独的表中。所以查询只针对所请求的较小表的行。

    但这有点高级https://www.postgresql.org/docs/current/static/ddl-partitioning.html

    【讨论】:

    • 忘记列participants。兄弟。如果规范化您的表结构(分为 2 个表:MessageConversation),如果在 Pagination Process 中,我们肯定需要在每个请求中按会话 ID 过滤消息。如果消息表中的行太多,我认为它太慢了!
    • 请在问题中提供您的用例和示例数据。你什么时候得到太多行?你在过滤什么。
    • 例如如果我们在Message表中有1M行,我们SELECT 10 FROM messages WHERE id_conversation = 42对于每个Pagination Request,它比我们SELECT FROM conversation WHERE id = 42慢并得到Message Column
    • 但是消息栏中的内容是什么?整个对话? SELECT 10 ...是什么意思
    • 是的。消息栏中的整个对话消息。
    猜你喜欢
    • 2023-04-06
    • 2018-06-01
    • 2016-04-27
    • 2019-02-12
    • 2012-04-03
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    相关资源
    最近更新 更多