Database design 私有消息设计

Database design 私有消息设计,database-design,Database Design,我正在开发一个新网站,我必须为我们的用户发送私人信息。我已经在其他项目上做过了,但那里的设计似乎并不正确(例如,我不能让超过两个人参与一条消息)。 那么,“正确”的方法是什么?我想为我的用户提供与Facebook相同的功能(同样,我已经这样做了,但感觉很脏:) 因此,系统应该支持2个或更多用户进行对话和线程式消息 我在想,一个解决方案是有两张这样的表格: 下午信息: id | pm |消息| id |用户| id |标题|内容|日期|时间 pm_收件人: id | pm |消息| id |用户|

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

我在想,一个解决方案是有两张这样的表格:

下午信息: id | pm |消息| id |用户| id |标题|内容|日期|时间

pm_收件人: id | pm |消息| id |用户| id |已|看到|删除

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


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

我不会说您在帖子中提出的实施方案一定是糟糕的。当然,它不是最简洁或最快的,但在我看来,它是人类最容易理解的。此外,删除逻辑应该不太难封装


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

如果可以有多个收件人,并且他们可以发送回复MSG,那么您需要处理的更多是某种聊天应用程序。您可以将“聊天”会话或会话存储在单独的表中,其中会话和参与者之间的关系为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

pm_messages表中的pm_messages_id列用于什么

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

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

    (评论太长)

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

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


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

    另一个用例来考虑(我知道我的用户想要这个)…他们都想要“发送邮件”。可以说在你打扫房子之前要考虑使用情况。 让我感到困扰的是这些信息 在全部删除之前,不要真正删除 收件人已删除该邮件 导致一些尴尬的消息 删除逻辑

    创建一个为您执行此操作的触发器。您的应用程序代码需要做的就是担心将“deleted”列设置为true,并在每个人都将消息标记为deleted时让UPDATE触发器对整个事件进行核爆


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

    没有干净的方法来跟踪谁见过或/或以这种方式删除消息。当然,除非我在你的提案中遗漏了什么?此外,除非绝对必要,否则我喜欢将我的表规范化……好吧,您只需使用另一个位向量场(其中每个位代表一个布尔标志)——它非常简单,可以实现,真的。我提出的解决方案可能不是最漂亮的,但如果你追求它,它肯定很快!不知道,听起来我必须在数据库中这样做才能得到想要的结果,我不知道MySQL是否支持这一点。(续)正如我最初所说的,你的第一种方法没有错。。。因此,如果您愿意,只需封装删除逻辑即可。除了速度的问题,它几乎可以归结为美学。尽管如此,我的解决方案似乎是有效的。。。我可以问一下,为什么投反对票?你有没有一些链接来展示你的方法?在我下决心之前,我想尝试不同的事情。我只是不完全理解您的解决方案是如何工作的:)两个表(您的对话和消息)与一个表(我的pm_消息)相比有什么好处?对话就像聊天会话。它可以包含许多消息。您可以使用我的设计来实现这一点,而且只需少一张表。还有其他ups吗?如果没有“对话”表,您将如何跟踪更改了标题之类内容的会话?老实说,对于快速脏的PM应用程序来说,双表方法似乎更好。但如果您需要跟踪“线程”,这种方法似乎更好。从某种意义上说,它不是一个简单的DELETE-FROM子句。我喜欢简单的:)这个
    DELETE FROM pm_messages
    RIGHT JOIN pm_recipients ON pm_messages.id = pm_recipients.pm_messages_id