代码之家  ›  专栏  ›  技术社区  ›  Jan Hančič

私信设计

  •  4
  • Jan Hančič  · 技术社区  · 16 年前

    我正在开发一个新网站,我必须为我们的用户制作私人消息。我已经在其他项目上做了这个,但是那里的设计似乎不正确(例如,我不能让两个人以上参与一个消息)。 那么,“正确”的方法是什么呢?我想为我的用户提供与Facebook相同的功能(同样,我已经这样做了,但感觉很脏:) 因此,系统应该支持会话和类似线程的消息中的2个或更多用户。

    我在想,一个解决办法是有两张这样的桌子:

    PMX消息: ID PM消息ID用户标题内容日期时间

    接受者: ID PM消息ID用户已看到已删除

    我将实际内容存储在“pm_messages”表中,并且将收件人(包括原始发件人)存储在“pm_recipients”表中。

    这是正确的方向还是我完全放弃了?让我感到困扰的是,在所有收件人删除邮件之前,邮件不会真正被删除,这会导致一些尴尬的删除逻辑。

    5 回复  |  直到 16 年前
        1
  •  6
  •   tehvan    16 年前

    如果可以有多个收件人,并且他们可以发送回复消息,那么您就需要处理某种聊天应用程序。您可以将“聊天”会话或会话存储在单独的表中,其中会话和参与者之间的关系为1-n,会话和消息之间的关系为1-n(如下表所示)。但最终,这当然取决于你。对于常规的消息发送,消息和收件人之间的1-N(如您所用)将起作用。

    table user:
    - id (pk)
    - name
    
    table conversation (one entry per "chat/messaging" session)
    - id (pk)
    - started_by_user_id
    - started_ts
    
    table conversation_participant (keeps track of all recipients)
    - id (pk)
    - conversation_id
    - user_id (refers to user.id)
    
    table message
    - id
    - conversation_id (refers to conversation.id)
    - sender (refers to user.id)
    - msg
    
        2
  •  1
  •   Noldorin    16 年前

    我不会说你在你的岗位上提出的实施方案必然是一个糟糕的方案。当然,它不是最简洁或最快的,但在我看来,它是人类最能理解的。此外,删除逻辑不应该很难封装。

    我建议的一个解决方案是使用一个单独的表来存储每个消息,其中包含发送者ID的字段,以及另一个字段,它是接收者ID的列表。当然,问题在于,考虑到通常没有数组/向量/列表类型,如何使用标准数据库类型之一来表示ID列表。我建议您使用varbinary(max)类型,如果它可用的话,将其视为一个位向量(比如,每个收件人ID 4个字节)。然后,您可以创建几个函数来对数组/列表进行非常简单的位编码/解码。

        3
  •  0
  •   Andrew Vit    16 年前

    pm_messages表中的pm_messages_id列用于什么?

    否则就有意义了…但我不明白为什么删除逻辑会很笨拙。您可以通过以下两种方式之一来处理:

    1. 用户删除后:如果没有其他收件人,则删除。
    2. 作为cron任务或稍后手动删除:没有理由需要立即执行此删除。它们只是孤儿记录,很容易找到:

    例如。:

    DELETE FROM pm_messages
    RIGHT JOIN pm_recipients ON pm_messages.id = pm_recipients.pm_messages_id
    
        4
  •  0
  •   Cory R. King    16 年前

    还要考虑一个用例(我知道我的用户希望这样做)…他们都想要一个“已发送邮件”。可以说,在你打扫房子之前,可能会考虑这个用例。

    令我困扰的是那些信息 在所有 收件人已删除 导致一些尴尬的信息 删除逻辑。

    创建一个触发器来为您执行此操作。您的应用程序代码需要做的就是担心将“已删除”列设置为“真”,并且当每个人都将消息标记为“已删除”时,更新触发器将触发整个事务。

    当然,接下来你要知道的是,你的用户需要取消删除。就我个人而言,我从不从数据库中删除消息,只是对用户隐藏它。

        5
  •  -1
  •   Dale Reidy    16 年前

    (评论时间太长)

    tehvans方法涉及存储特定对话的参与者列表,而在您的方法中,参与者是按消息存储的。我认为这样做的原因是允许删除和读取标记,问题是-为什么这样做?

    论坛通常不要求您将会话的每个部分标记为已读,因此在参与者表中存储最后一个已读时间戳,这样,在时间戳之后创建/修改的任何消息都可以突出显示。

    在(几乎)所有情况下,论坛消息的删除都是由作者/管理员完成的,并导致消息从所有用户的视图中删除。