【问题标题】:Database Design for Facebook-like messages [closed]类似 Facebook 的消息的数据库设计 [关闭]
【发布时间】:2011-01-18 23:04:33
【问题描述】:

我目前正在计划一个使用 PHP/MySQL 的新系统,并希望确保我的数据库能够处理我计划存储的数据量。我的新项目的功能之一是像 Facebook 这样的“消息”功能。我想确保为最终用户创造最佳体验。该网站最终将共同处理 1000 名用户和数百万条消息。数据库设计的最佳方法是什么? MySQL 甚至是正确的数据库吗?

【问题讨论】:

  • 问模糊的问题,得到模糊的答案!
  • 是我自己还是“类似 Facebook 的消息”和“为最终用户提供最佳体验”是矛盾的?

标签: php sql mysql database database-design


【解决方案1】:

我想说阅读有关面向对象的数据库和 nosql 系统的信息,这是一个非常有趣的概念,被著名的框架(如 Ruby on rails)积极使用,它可以让您减少对数据的担忧,因为您可以简单地转储您的对象直接进入数据库,我知道这有点离题,但不太复杂的数据库意味着更容易过渡 进入可扩展系统,我只是在传播意识

然而,权衡是,没有像关系数据库那样强大的用户群,这使得在您进行过程中更难找到问题的答案,并且适应使用它所需的时间同样长,但包含数据无需在每个阶段都考虑数据库设计,编写业务逻辑是一件了不起的事情,并且可以加快您的开发时间,但是稍后,当您遇到瓶颈和性能问题时,由于周围的帮助较少,因此将更难解决。

【讨论】:

    【解决方案2】:

    如果您正确设计数据库,性能应该会随着数据量的增加而恶化logarithmically。换句话说,执行查询的时间将比数据量增长得慢得多。

    要实现这一目标,您必须在许多事情上自律:

    • 您的数据库设计必须合理。了解ER modeling 和规范化是必不可少的。理解anatomy of indexes 和其他物理数据结构也是如此。
    • 拥有一个良好的规范化数据库后,请考虑是否应该出于性能原因对它的某些“边缘”进行明智的非规范化。
    • 在整个过程中,请记住您的客户端应用程序1 会执行哪些类型的查询:
      • 相应地设计索引 - 专门为您知道自己需要的查询编制索引,不要过度索引!
      • 某些设计决策(例如使用自然键与代理键以及识别与非识别关系)可能会影响您需要的 JOIN 数量。
      • 尽量让您的数据库设计对集群范围扫描、index-only scans 等保持友好。
    • 使用 DBMS 特定的机制,例如clustering、分区、密钥压缩、物化视图(等等)对您有利。如果 DBMS 不支持您认为必不可少的某些机制,请不要害怕切换 DBMS!例如,InnoDB tables are always clustered,这在查询 PK 时是一个优势,但如果您需要二级索引,则可能是一个劣势。如果您需要集群表和基于堆的表,请使用同时支持它们的一些 DBMS(例如 Oracle 或 MS SQL Server)。2
    • 仔细编码客户端应用程序。虔诚地使用绑定参数和查询preparation - 您不仅可以最大限度地减少 SQL 解析和查询计划开销,而且还可以抵抗 SQL 注入! ORM 和库通常会阻止您手动执行此操作,但您仍然应该了解“幕后”发生的事情。
    • 最后但同样重要的是,不要依赖假设 - 而是测量!数据库性能可能是一种精细(且相当复杂)的平衡行为,某些决策的影响可能不会立即显现

    如果您正确执行所有这些操作,则必须在“经典”DBMS 不再适用之前接近 Facebook 的实际数据量。在这种情况下,数以千计的用户和数百万或消息甚至不符合“大”的条件。


    1 从 DBMS 的角度来看,一个“客户端”——这也可能是一个中间层。

    2 MyISAM 也不是集群的,但有严重的限制(例如缺乏事务支持),无论如何都会使其无法正常使用。

    【讨论】:

      【解决方案3】:

      分片对于您的“广泛”基础的要求当然不是必需的...我已经处理了大量数据,甚至没有考虑分区表和分片实现,直到有许多表容纳超过 10 亿条记录(然后加入这些可能会有点慢)。使用智能键为您的表建立索引,您甚至可以考虑使用 eav 类型结构来保持表的范围窄并减轻查询时返回 null 的问题。

      以上是半睡半醒时写的,所以请忽略错别字;)

      【讨论】:

        【解决方案4】:

        Facebook 从 MySQL 开始,直到他们拥有超过 1 亿用户的 7TB 收件箱数据时才迁移到 Cassandra

        来源:Lakshman, Malik: Cassandra - A Decentralized Structured Storage System

        【讨论】:

        • 没错,从小处着手,保持低成本。仅仅因为你想成为下一个 Facebook 并不意味着你需要花费任何金钱或时间来设计一个如此广泛的系统。每个成功的网站都以简单、快速和廉价的方式开始。过度设计您的系统会产生“过早优化”的恶臭。
        【解决方案5】:

        如果您的意思是“对于消息系统,我的 mysql 表应该是什么样的”,我在消息系统中使用以下列:

        message_id
        fromuser
        fromview
        fromstatus
        touser
        toview
        tostatus
        title
        text
        poston
        thread
        

        显然,Message_id 是 auto_increment。 Fromuser 和 touser 很明显。 Fromstatus 和 tostatus 处于活动状态、已删除、清除、草稿等。 Fromview 和 toview 设置为“是”和“否”。标题、文本和“邮寄”日期是显而易见的。根据您的 html 表单和消息显示脚本,线程可能需要您付出一些努力。

        为您的表单创建一个基于“to:”字段的 foreach 循环,并为每个收件人保存一份副本。

        我希望这个消息系统能够容纳数百万,但数百万可能还需要几年时间。我保持它小而简单。

        【讨论】:

          【解决方案6】:

          你对你想学的东西不是很精确。好的。我会尽力给你一些建议。

          1. 标准化
          2. 索引
          3. MyISAM 用于高负载下的表
          4. 非规范化(原文如此!),但你应该明白你在做什么
          5. 分片
          6. 简约的 DB 层实现灵活性

          【讨论】:

            【解决方案7】:

            只要您正确设计数据库,MySQL 处理数百万或数亿条记录是没有问题的。

            话虽如此,“像 Facebook 这样的消息功能”是一个相当广泛的定义。通常,您将定义一个messages 表,将每条消息链接到创建它的用户(即,在消息表中有一个userId 列)。如果您希望消息发送给多个用户,您有一个message_recipients 表,通过存储由messageIdrecipientId 组成的多条记录来定义一对多关系。将正确的索引添加到这些表中,您就完成了 80% 的工作。

            话虽如此,剩下的 20% 可能是一个杀手。不幸的是,您如何使用数据库将决定您还需要做什么,并且您必须在做出这些判断之前提供有关您的应用程序的更多详细信息。例如,您可能希望考虑使用自动归档解决方案,使主表保持相对较小,并将旧数据移动到可以在必要时访问的备份表中。您可能不会马上需要它,但它在未来可能会有所帮助。

            【讨论】:

            • 根据我的经验,几乎每个人或公司在规划系统时都会将他们的需求夸大 10 到 100 倍。如有疑问,从简单开始,购买 1 台服务器并从中运行 Web 服务器和数据库。在您需要它们之前,不要担心多台服务器。从第一天开始就拥有多台服务器的唯一原因是因为您希望进行故障转移,即便如此,您也可能会发现初始成本超出了您的需求。
            • @TravisO,至少对于 SQL 服务器,您甚至不应该将它与其他任何东西放在服务器上。 SQl 服务器的设计目的是使用服务器的所有内存,并且做的更少就是削弱它。
            【解决方案8】:

            如果您预算有限,请从 MySQL 开始,然后使用 Zend::DB 之类的系统或更高级别的 Doctrine。

            让切换 DMBS 变得容易比一开始就选择你的 DBMS 更重要。

            【讨论】:

              【解决方案9】:

              只要你把你的表设置成关系型,设置好表之间的关系,MySQL就应该没问题。

              我也可以推荐 Postgres 吗?

              【讨论】:

              • 我在 MySQL、PostGres 和 MS SQL 方面拥有相同的经验...我更喜欢 MS SQL,但由于启动成本在新项目中非常重要,因此我更喜欢 PostGres项目。
              【解决方案10】:

              如果您打算处理大量数据(当然数百万甚至达不到这么大的规模),那么请聘请数据库专业人士。针对大型数据集进行高效和有效的数据库设计是一个复杂的问题,需要专家。

              在回答您的问题时,是的,如果设计良好,mysql 可以轻松处理数百万条记录,而如果设计不佳,这将是一场噩梦,就像任何其他现代数据库一样。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-08-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-10-19
                • 2011-09-06
                相关资源
                最近更新 更多