【发布时间】:2011-11-21 04:42:15
【问题描述】:
我一直想知道 facebook 如何为您可以“喜欢”的所有不同事物管理数据库设计。如果只有一件事值得喜欢,这很简单,只是你喜欢什么的外键和你是谁的外键。
但必须有数百个不同的表可以在 facebook 上“点赞”。他们如何存储喜欢的?
【问题讨论】:
标签: facebook database-design facebook-like
我一直想知道 facebook 如何为您可以“喜欢”的所有不同事物管理数据库设计。如果只有一件事值得喜欢,这很简单,只是你喜欢什么的外键和你是谁的外键。
但必须有数百个不同的表可以在 facebook 上“点赞”。他们如何存储喜欢的?
【问题讨论】:
标签: facebook database-design facebook-like
如果您想在关系数据库中表示这种结构,那么您需要使用通常称为表继承的层次结构。在表继承中,您有一个定义 parent 类型的表,然后是 child 表,其主键也是返回到父级的外键。
使用 Facebook 示例,您可能会遇到这样的情况:
User
------------
UserId (PK)
Item
-------------
ItemId (PK)
ItemType (discriminator column)
OwnerId (FK to User)
Status
------------
ItemId (PK, FK to Item)
StatusText
RelationshipUpdate
------------------
ItemId (PK, FK to Item)
RelationshipStatus
RelationTo (FK to User)
Like
------------
OwnerId (FK to User)
ItemId (FK to Item)
Compound PK of OwnerId, ItemId
在兴趣完整性方面,值得注意的是,Facebook 并未将 RDBMS 用于此类事情。他们为这种存储选择了 NoSQL 解决方案。然而,这是在 RDBMS 中存储此类松散耦合信息的一种方式。
【讨论】:
Facebook 没有传统的外键等,因为他们的大部分数据存储不使用关系数据库。简而言之,他们不会为此而削减它。
但是他们使用了几种 NoSQL 类型的数据存储。 “Like”很可能是基于服务,可能在整个基础设施中以 SOA 风格的方式设置的。这样,“喜欢”基本上可以归因于他们希望与之相关的任何事物。所有这一切,都具有巨大的可扩展性,并且无需处理紧密耦合的关系问题。 Facebook 无法以他们的运营量处理的事情。
他们也可以使用 AOP(面向方面编程)风格的处理机制来“附加”一个“喜欢”到任何在页面呈现时可能需要一个的东西,但我认为这是通过 JavaScript 异步处理针对SOA 风格的 Web 服务或其他交付机制。
不管怎样,我很想听听他们自己是如何从架构的角度来进行这种设置的。考虑到它们的数量,即使是简单的“Like”按钮也成为一项重要的技术实现。
【讨论】:
您可以有一个带有 Id、ForeignId 和 Type 的表。类型可以是照片、状态、事件等任何东西…… ForeignId 将是表类型中记录的 id。这使得 cmets 和 likes 都成为可能。你只需要一张表来放所有的赞,一张放所有的 cmets 和我描述的那张。
例子:
Items
Id | Foreign Id | Type
----+-------------+--------
1 | 322 | Photo
4 | 346 | Status
Likes
Id | User Id | Item Id
----+-------------+--------
1 | 111 | 1
在这里,ID 为 111 的用户喜欢 ID 为 322 的照片。
注意:我假设您使用的是 RDBMS,但请参阅 Adron 的回答。 Facebook 确实不对其大部分数据使用 RDBMS。
【讨论】:
Photo 或Status 表的主键也是返回Item 的外键。
我很确定 Facebook 不会像其他人使用 RDBMS 建议的那样存储“喜欢”信息。拥有数百万用户,可能还有数千个赞,我们正在考虑加入数千行,这会影响性能。
这里最好的方法是将所有“喜欢”附加在一行中。例如,具有文本数据类型的 user_like_id 列的表。然后附加所有喜欢该帖子的ID。在这种情况下,您只需查询一行即可获得所有信息。这将比加入表格和获取计数要快得多。
编辑:我最近没来过这个网站,我刚刚发现这个答案被否决了。好吧,这是一个example post with like count and their avatars。这是我的设计,我刚刚实现了我所说的。
这里的两个组件是 1.) XREF 表和 2.) JSON 对象。
喜欢的内容仍存储在 XREF 表中。但同时,数据会附加在 JSON 对象上,并存储在 post 表的文本列中。
为什么我将文本列中的点赞信息存储为 JSON?这样就不需要为喜欢做数据库查找/加入。如果有人与帖子不同,则 JSON 对象将被更新。
现在我不知道为什么这里的一些用户不赞成这个答案。这个答案提供了快速的数据检索。这接近 NoSQL 方法,这是 FB 访问数据的方式。在这种情况下,不需要额外的连接/查找来获取喜欢的信息。
这是容纳喜欢的表格。这只是用户和项目表之间的简单外部参照映射。
【讨论】: