【问题标题】:Comparing two db designs for internal messaging比较内部消息传递的两个数据库设计
【发布时间】:2011-12-17 02:29:47
【问题描述】:

以下哪种数据库设计更适合内部消息传递系统。

三个表:

MessageThread(models.Model):
    - subject
    - timestamp
    - creator

Message(models.Model):
    - thread (pk)
    - content
    - timestamp
    - sender

MessageRecipient
    - message_id (pk)
    - recipient (pk)
    - status (read, unread, deleted)

两个表:

Message
    - thread_id
    - subject
    - content
    - timestamp
    - sender (fk)

MessageRecipient
    - message_id (fk)
    - recipient (fk)
    - status (read, unread, deleted)

一个比另一个有什么优势?谢谢。

【问题讨论】:

    标签: mysql sql database-design django-models


    【解决方案1】:

    第一个优势

    第一个模式遵循更好的规范化规则,因此在大多数情况下可能更好。

    拥有一个thread_id,它基本上是一个自然键,而不是另一个表的 FK,这可能是自找麻烦。当你想要它是独一无二的,当你想要它是一样的时候,很难强制它是独一无二的。出于这个原因,我会鼓励第一个建议的架构。

    秒的优势

    您的第二个架构允许为线程中的每条消息更改主题。如果这是您想要的功能,则不能使用第一个选项,因为您已经编写了它(但请参见下文)。

    其他选项

    Message
        - id
        - parent (fk to Message.id)
        - subject
        - content
        - timestamp
        - sender (fk)
    
    MessageRecipient
        - message_id (fk)
        - recipient (fk)
        - status (read, unread, deleted)
    

    您可以使用parent 概念来代替thread_id 概念。然后每个回复都会指向原始消息的记录。这允许在没有“线程”表的情况下进行线程化。另一个可能的优点是它也允许 线程树。简而言之,您可以通过这种方式表示消息和回复之间更复杂的关系。如果您不关心这一点,那么这不会成为您申请的奖励。

    如果您不关心我刚才提到的线程优势,我可能会推荐您的两种模式的混合:

    MessageThread(models.Model):
        - id
    
    Message(models.Model):
        - thread (pk)
        - subject
        - content
        - timestamp
        - sender
    
    MessageRecipient
        - message_id (pk)
        - recipient (pk)
        - status (read, unread, deleted)
    

    这类似于第一个模式,除了我将“主题”列从MessageThread 移动到Message 表,以允许主题随着线程的进展而改变......我只是使用MessageThread 表作为对 Message 中使用的线程 ID 的约束(它克服了我在回答开头提到的限制)。您可能还想在 MessageThread 表中包含其他元数据,但我将由您和您的应用程序来决定。

    【讨论】:

      【解决方案2】:

      如果稍后您想添加一些额外的线程属性,例如“锁定”、“粘性”或“重要”,单独的 MesageThread 表会很有用。不过,仅仅为了将来可能添加其他功能而选择更复杂的模型通常不是一个好主意。

      第一个模型(带有 MessageThread 表的模型)保证线程中的所有消息都有相同的主题,在第二个模型中,线程中的每条消息都可以有不同的主题。这可能是好事也可能是坏事,这取决于您希望消息如何工作。

      第一个模型可以将message.thread_id 列声明为外键,因此您不能在没有有效线程引用的情况下插入消息。对于第二个模型,你没有那个保证。这可能会在以后导致一些错误。

      我不认为第一个模型中的MessageThread.timestampMessageThread.creator 列是真正需要的;与线程中第一条消息的时间戳和创建者不一样吗?这种冗余可能会产生负面影响。

      我会使用第一个模型,但我会从MessageThread 中删除创建者和时间戳字段。

      【讨论】:

        猜你喜欢
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 2011-11-28
        • 2017-10-29
        • 2011-05-29
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多