我一直在想,Facebook如何管理数据库设计的所有不同的东西,你可以“喜欢”。如果只有一件事喜欢,这很简单,只是你喜欢的外键和你是谁的外键。Facebook的“喜欢”的数据结构
但是,必须有数百个您可以在Facebook上“喜欢”的不同表格。他们如何存储喜欢?
我一直在想,Facebook如何管理数据库设计的所有不同的东西,你可以“喜欢”。如果只有一件事喜欢,这很简单,只是你喜欢的外键和你是谁的外键。Facebook的“喜欢”的数据结构
但是,必须有数百个您可以在Facebook上“喜欢”的不同表格。他们如何存储喜欢?
如果你想表示这种结构在关系数据库中,那么你需要使用通常被称为表继承层次结构。在表继承,你有一个定义父类型,然后孩子表,其主键也是外键回父单个表。
使用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中存储这种松散耦合信息的一种方式。
您可以使用Id,ForeignId和Type表。类型可以是任何类似照片,状态,事件等... ForeignId将是表中Type记录的ID。这使得评论和喜欢成为可能。你只需要一张桌子就可以满足所有喜好,其中一张是所有评论,另一张是我所描述的。
例子:
Items
Id | Foreign Id | Type
----+-------------+--------
1 | 322 | Photo
4 | 346 | Status
Likes
Id | User Id | Item Id
----+-------------+--------
1 | 111 | 1
这里,编号111的用户喜欢用编号322
注意照片:我假设你使用的是RDBMS,但见阿德伦的答案。 Facebook不会为而不是对其大部分数据使用RDBMS。
Facebook并没有传统的外键和这样的,因为它们不使用关系数据库的大部分数据存储。简而言之,他们不会为此而削减它。
但是他们使用了几个NoSQL类型的数据存储。 “Like”很可能是基于服务的,可能在整个基础架构中以SOA风格的方式进行设置。这样,“喜欢”基本上可以归因于他们希望与之相关联的任何东西。所有这些,具有广泛的可扩展性和没有紧密耦合的关系问题来处理。 Facebook在他们运营的数量上无法真正负担得起的东西。
他们也可以使用AOP(Aspect Oriented Programming)风格的处理机制将“Like”附加到页面渲染时可能需要的任何东西上,但是我得到这样的概念,即通过JavaScript进行异步处理针对SOA风格的Web服务或其他交付机制。
无论哪种方式,我很想听听他们如何有一个从建筑角度来看自己这个设置。考虑到它们的体积,即使简单的“赞”按钮也成为技术的重要实现。
-1。 “他们不会为此而削减”是一个意见和很多猜测的问题。这个答案的唯一部分实际上解决了这个问题(如何存储这些东西)就是你的第二段。 –
+1 @adam,简单的技术事实,没有涉及的意见。 RDBMS针对不同的使用模式而设计。 –
像@StephanEggermont指出亚当他们是为了不同的模式,不同的目的,Facebook需要更多。我不是在猜测,普通数据库社区和科学界对此表示赞同。这就是其他解决方案存在的原因。 #justsayin 至于你上面的断言,键没有以这种方式对齐。这是一种适用于RDBMS的方式,但RDBMS无法提供或处理Facebook处理的数据。 Facebook没有试图放弃RDBMS,只是因为他们想写点别的东西。 – Adron
我很确定Facebook不会像其他人一样使用RDBMS存储“like”信息。随着数百万用户和可能数千人的喜欢,我们正在考虑成千上万行加入这里,这会影响性能。
这里最好的方法是在单行中追加所有“喜欢”。例如,具有文本数据类型的user_like_id列的表。然后附加所有喜欢该帖子的ID。在这种情况下,你只查询一行,你就得到了一切。这将比连接表格和计数快很多。
编辑:我最近没有在这个网站上,我刚刚发现这个答案已经downvoted。那么,这是一个example post with like count and their avatars。这是我的设计,我刚刚实施了我正在谈论的内容。
这里的两个组件是1.)XREF表和2)JSON对象。
喜欢的东西仍然存储在XREF表中。但是与此同时,数据被附加在JSON对象上并存储在帖子表的文本列中。
为什么我将喜欢的信息作为JSON存储在文本列上?这样就不需要为喜欢的人做db查找/连接。如果有人不像帖子,JSON对象只是更新。
现在我不知道为什么这个答案是由这里的一些用户downvoted。这个答案提供了快速数据检索。这接近于NoSQL的方法,它是如何访问数据的FB。在这种情况下,不需要额外的连接/查找来获取喜欢信息。
而这里是表格,持有喜欢。这只是用户和项目表之间简单的XREF映射。
这可能是一个解决方案,我认为问题是“everyhing”必须是一个“Item”,因为如果你有一个不是Item的表,并且有一天你也想要一个表,那会发生什么?我认为有时候越简单越好,为什么不做相反的继承?就像父母,你有一个FK状态的like_for_status表,like_for_photo等,你可以很容易地将它扩展到任何表,并且你的查询也更快。 – Enrique
+1,但我认为你的意思是**每种类型**或TPT。 – Yuck
@Yuck:是的,TPT(而不是按层次结构),尽管TPT和TPH是我所知的实体框架词汇的一部分,而不是更普遍的SQL。 –