【问题标题】:Single mysql table for private messaging用于私人消息传递的单个 mysql 表
【发布时间】:2011-10-08 18:24:37
【问题描述】:

我正在尝试为网站上的私人消息创建一个表。我创建了下表,我认为它是有效的,但我非常感谢一些反馈。

CREATE TABLE IF NOT EXISTS `pm` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `to` int(11) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `subject` varchar(255) DEFAULT NULL,
  `message` text NOT NULL,
  `read` tinyint(1) NOT NULL DEFAULT '0',
  `deleted` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
  FOREIGN KEY (user_id) REFERENCES User(user_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

我有 2 列确定消息的状态:readdeleted

如果read = 1,则消息已被接收方读取。如果deleted = 1,则发送者或接收者从已发送或已接收的收件箱中删除了该消息。如果deleted = 2 两个用户都删除了该消息,则从数据库表中删除该行。

【问题讨论】:

  • 用这么少的信息很难评估这张表的有效性。 MySQL 用于保存数据。该表保存数据。这张表是否足以用于消息传递系统?是的,它为消息传递系统的核心必需品提供了空间。除此之外,如果不知道您打算如何使用它、引用它、如何构建应用程序、将使用什么设计方法等,就无法判断此实现的实用性。

标签: php mysql database database-design


【解决方案1】:

我看到您没有明确说明任何索引。在您的表上拥有适当的索引可以显着提高您的性能。我还相信,对于您的消息列,您可能需要考虑将 i 设为明确规定最大大小的 varchar。除了您可能已经照顾好您的桌子的那两个项目之外,我对我来说看起来还不错。

MySQL 表性能指南:

  1. 为表添加适当的索引。 索引不仅用于主键/唯一键,还可以将它们添加到经常引用的列中。
  2. 明确说明最大长度。 固定长度的表格比它们的对应速度更快
  3. 总是有一个 id 列。
  4. 尽可能添加 NOT NULL。 空值仍然占用空间
  5. 了解您的数据类型。 知识就是力量,可以节省性能和空间

趣味文章:
VarChar/TEXT Benchmarks
Similar Question
Some Best Practices
Data Type Storage Requirements

我列出的文章和一些项目可能不是 100% 正确或可靠的,因此如果您有兴趣进一步调整性能,请确保自己进行一些研究。

【讨论】:

    【解决方案2】:

    几个cmets:

    Charset=latin1 会惹恼一些人,我建议charset=utf8

    我建议不仅在user_id 上添加外键签入,还对to 进行签入。

    我还会在date 上添加一个索引,因为您将对该字段进行大量排序。

    你需要在两个字段中拆分删除,否则你将不知道哪个用户删除了该消息。 (deleted_by_user, deleted_by_recipient)

    请注意,date 是保留字,您需要在查询中将其更改为 message_date`backtick`

    【讨论】:

    • 谢谢!这些都是极好的建议。我会在发送者和接收者上放置外文以避免重复消息,是吗?不会因为索引也需要更新而在日期上添加索引会减慢更新速度吗?并且更新会经常发生。这是我唯一关心的问题。
    • @Cyber​​Junky,显示按date 排序的消息也会很多因此维护插入和更新索引的额外成本将超过@987654332 的偏移量@时间恕我直言。
    【解决方案3】:

    一些cmets:

    还不错。

    我会将表格命名为其他人可能会根据上下文猜测的名称。所以也许是 private_message 而不是 pm。

    i 会明确指定用户列名,因此可能是 from_user_id 和 to_user_id 而不是 'user_id' 和 'to'

    我会考虑将状态提取到一个包含状态、用户 ID 和日期的新表中 - 这应该让您更灵活地了解谁随着时间的推移对消息执行什么操作。

    【讨论】:

      【解决方案4】:

      为了同时显示收件人的收件箱和发件人的发件箱(并能够分别删除邮件),您可能需要更多信息,而不是您当前已编码的信息。我会建议为每一方“删除”字段。 (只要这限制为每端只有 1 个用户并且没有广播消息,这是可行的。但是,这不能扩展到广播消息,这需要超过 1 个表才能有效地完成)

      【讨论】:

        【解决方案5】:

        您可能还想强制与ON DELETEON UPDATE 建立关键关系:

        FOREIGN KEY (user_id) REFERENCES User(user_id) ON DELETE CASCADE ON UPDATE CASCADE,
        FOREIGN KEY (to) REFERENCES User(user_id) ON DELETE CASCADE ON UPDATE CASCADE
        

        用户的删除或修改会将更改或删除传播到消息表。

        【讨论】:

        • 谢谢!我也在计划,不知道具体怎么做。 :)
        【解决方案6】:

        我认为您可能需要添加一个名为 Parent_Message_ID 的列,该列将具有父邮件 ID。这样回复也可以包括在内。 如果您认为将来要对您的私人消息添加回复。

        【讨论】:

        • 感谢您的建议,我正在考虑。但是,我认为将回复添加为普通消息会更简单,但在原始消息周围添加 标签,并在主题字段上添加 Re:。如果我特别想显示我的所有回复,我认为需要 parent_message_id。
        • 您会在回复中存储问题的所有文本吗?
        • 当然,就像在电子邮件中一样。在回复时,用第一条消息填充文本区域,用户可以在上面写下他/她的消息。作为事后的想法,父消息列可能会更好,因此我不必重新输入文本并具有较大的值。
        • 您还可以有回复、评论、提醒等消息类型。这些字符串可以在单独的表中,并且您的主表将有一个列 message_type... 基于此您可以发送提醒(将禁用回复),或允许用户添加评论,因此您的主表是消息表。您在单独的表格中有消息主题和文本,用户可以检查提醒...但是这些将根据您想要的功能/流程..因此添加到 cmets
        • 你的意思是所有与消息相关的一个表和另一个表来处理每一行是什么类型的消息?这是个好主意,但我只会将“消息类型”放在与消息相同的表中的列上,然后相应地更改其状态。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        • 2015-12-01
        相关资源
        最近更新 更多