面向Facebook的消息的数据库设计

时间:2010-02-19 20:57:10

标签: php sql mysql database database-design

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

10 个答案:

答案 0 :(得分:16)

只要您正确设计数据库,MySQL对数百万或数亿条记录没有任何问题。

话虽如此,“像Facebook这样的消息功能”是一个相当广泛的定义。通常,您将定义一个messages表,该表将每条消息链接到创建它的用户(即,在消息表中有一个userId列)。如果您希望将消息发送给多个用户,则可以通过存储由message_recipientsmessageId组成的多个记录来定义1对多关系的recipientId表。为这些表添加适当的索引,你就是那里的80%。

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

答案 1 :(得分:11)

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

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

答案 2 :(得分:7)

如果您计划处理大量数据(当然数百万甚至没有接近合格的数据),那么聘请数据库专业人员。大数据集的高效且有效的数据库设计是一个复杂的问题,需要专家。

在回答你的问题时,如果设计很好,mysql可以轻松处理数百万条记录,如果设计不好就会成为一场噩梦,就像任何其他现代数据库一样。

答案 3 :(得分:3)

如果您正确设计了数据库,性能会随着数据量的增加而降低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的数据量。在这种情况下,1000个用户和数百万或消息甚至不符合“大”的条件。


1 从DBMS角度看“客户” - 这也可能是一个中间层。

2 MyISAM也没有群集,但有严重的限制(例如没有交易支持),无论如何都应该取消它的正常使用资格。

答案 4 :(得分:2)

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

更容易切换DMBS然后在开始时选择您的DBMS。

答案 5 :(得分:1)

只要您将表设置为关系并设置表之间的关系,MySQL应该没问题。

我可以建议Postgres吗?

答案 6 :(得分:0)

您对自己想要学习的内容并不十分准确。好的。我会尽力给你一些建议。

  1. 正常化
  2. 索引
  3. 高负荷表格的MyISAM
  4. 非规范化(原文如此!),但你应该明白你在做什么
  5. 拆分
  6. 简化DB层以提高灵活性

答案 7 :(得分:0)

对于您的“基于广泛”的要求来说,分片肯定不是必需的......我已经处理了大量的数据,甚至没有考虑分区表和分片实现,直到有许多表包含超过10亿条记录(然后加入那些可能会有点慢)。使用智能键对表进行索引,甚至可以考虑使用eav类型结构来保持表的缩小,并减轻查询的空返回。

上面写着半睡半醒,所以忽略错别字;)

答案 8 :(得分:0)

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

message_id
fromuser
fromview
fromstatus
touser
toview
tostatus
title
text
poston
thread

显然,Message_id是auto_increment。 Fromuser和touser很明显。 Fromstatus和tostatus是活动的,删除,清除,草稿等。 Fromview和toview设置为“yes”和“no”。标题,文字和'poston'日期显而易见。根据您的html表单和消息显示脚本,线程可能需要您的一些努力。

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

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

答案 9 :(得分:0)

我说的是关于面向对象数据库以及nosql系统的阅读,它是一个非常有趣的概念,被Ruby on rails这样的着名框架主动使用,它可以让你更少担心你的数据,因为你可以简单地转储你的对象直接进入数据库,我知道它有点偏离主题,但不太复杂的数据库意味着更容易过渡 进入可扩展的系统,我只是传播意识

然而,权衡的是,没有像关系数据库那样强大的用户群,这使得在进行过程中更难找到问题的答案,并且在适应使用它时需要更长的时间,但包含数据在没有考虑每个阶段的数据库设计的情况下编写业务逻辑是一件令人惊奇的事情,并且加快了开发时间,但是后来,当你面临瓶颈和性能问题时,由于周围的帮助较少,因此难以解决。 / p>