2011-09-20 107 views
26

我一直在想,Facebook如何管理数据库设计的所有不同的东西,你可以“喜欢”。如果只有一件事喜欢,这很简单,只是你喜欢的外键和你是谁的外键。Facebook的“喜欢”的数据结构

但是,必须有数百个您可以在Facebook上“喜欢”的不同表格。他们如何存储喜欢?

回答

24

如果你想表示这种结构在关系数据库中,那么你需要使用通常被称为表继承层次结构。在表继承,你有一个定义类型,然后孩子表,其主键也是外键回父单个表。

使用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中存储这种松散耦合信息的一种方式。

+0

这可能是一个解决方案,我认为问题是“everyhing”必须是一个“Item”,因为如果你有一个不是Item的表,并且有一天你也想要一个表,那会发生什么?我认为有时候越简单越好,为什么不做相反的继承?就像父母,你有一个FK状态的like_for_status表,like_for_photo等,你可以很容易地将它扩展到任何表,并且你的查询也更快。 – Enrique

+0

+1,但我认为你的意思是**每种类型**或TPT。 – Yuck

+0

@Yuck:是的,TPT(而不是按层次结构),尽管TPT和TPH是我所知的实体框架词汇的一部分,而不是更普遍的SQL。 –

0

您可以使用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。

+0

但你不能使用的限制,在“外部ID” – Enrique

+0

@Enrique你能不能解释一下?只有在使用RI约束的表格继承模式中,什么可以执行和不能执行,当然都有限制,但是目前还不清楚你在说什么。 –

+0

@Adam Robinson“Items”表中的“Foreign_Id”列不是真正的FK,因为您无法将它指向任何表,因为它实际上指向很多表(取决于“类型”列),所以你不能在那里放一个FK(因此是一个约束)。这可能会使您的数据不一致。 – Enrique

2

Facebook并没有传统的外键和这样的,因为它们不使用关系数据库的大部分数据存储。简而言之,他们不会为此而削减它。

但是他们使用了几个NoSQL类型的数据存储。 “Like”很可能是基于服务的,可能在整个基础架构中以SOA风格的方式进行设置。这样,“喜欢”基本上可以归因于他们希望与之相关联的任何东西。所有这些,具有广泛的可扩展性和没有紧密耦合的关系问题来处理。 Facebook在他们运营的数量上无法真正负担得起的东西。

他们也可以使用AOP(Aspect Oriented Programming)风格的处理机制将“Like”附加到页面渲染时可能需要的任何东西上,但是我得到这样的概念,即通过JavaScript进行异步处理针对SOA风格的Web服务或其他交付机制。

无论哪种方式,我很想听听他们如何有一个从建筑角度来看自己这个设置。考虑到它们的体积,即使简单的“赞”按钮也成为技术的重要实现。

+0

-1。 “他们不会为此而削减”是一个意见和很多猜测的问题。这个答案的唯一部分实际上解决了这个问题(如何存储这些东西)就是你的第二段。 –

+0

+1 @adam,简单的技术事实,没有涉及的意见。 RDBMS针对不同的使用模式而设计。 –

+0

像@StephanEggermont指出亚当他们是为了不同的模式,不同的目的,Facebook需要更多。我不是在猜测,普通数据库社区和科学界对此表示赞同。这就是其他解决方案存在的原因。 #justsayin 至于你上面的断言,键没有以这种方式对齐。这是一种适用于RDBMS的方式,但RDBMS无法提供或处理Facebook处理的数据。 Facebook没有试图放弃RDBMS,只是因为他们想写点别的东西。 – Adron

-5

我很确定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映射。

enter image description here

+0

那你怎么知道'有多少人喜欢这个'?查询用户表中的所有行? – Wint

+0

最糟糕的解决方案;) – Pars

+0

@Pars最差的回复;) – Ross