当前位置:  开发笔记 > 数据库 > 正文

Facebook数据库设计?

如何解决《Facebook数据库设计?》经验,为你挑选了9个好方法。

我一直想知道Facebook如何设计朋友< - >用户关系.

我认为用户表是这样的:

user_email PK
user_id PK
password 

我用用户的数据(性别,年龄等通过用户电子邮件连接,我会假设)来计算表格.

它是如何将所有朋友连接到此用户的?

像这样的东西?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

可能不是.因为用户数量未知并且将会扩展.



1> TheTXI..:

保持一个朋友表,其中包含UserID,然后是朋友的UserID(我们将其称为FriendID).两列都是返回Users表的外键.

一些有用的例子:

Table Name: User
Columns:
    UserID PK
    EmailAddress
    Password
    Gender
    DOB
    Location

TableName: Friends
Columns:
    UserID PK FK
    FriendID PK FK
    (This table features a composite primary key made up of the two foreign 
     keys, both pointing back to the user table. One ID will point to the
     logged in user, the other ID will point to the individual friend
     of that user)

用法示例:

Table User
--------------
UserID EmailAddress Password Gender DOB      Location
------------------------------------------------------
1      bob@bob.com  bobbie   M      1/1/2009 New York City
2      jon@jon.com  jonathan M      2/2/2008 Los Angeles
3      joe@joe.com  joseph   M      1/2/2007 Pittsburgh

Table Friends
---------------
UserID FriendID
----------------
1      2
1      3
2      3

这将表明Bob是Jon和Joe的朋友,Jon也是Joe的朋友.在这个例子中,我们假设友谊总是两种方式,因此你不需要表中的一行,如(2,1)或(3,2),因为它们已经在另一个方向上表示.对于友谊或其他关系不是明确双向的示例,您还需要使用这些行来指示双向关系.


想想这是多么低效 - 你必须对多对多,平均加倍搜索时间的列进行析取查询.
**你可以肯定facebook没有使用RDBMS,众所周知,他们,twitter和其他需要运行此类查询的人使用某种风格的图形数据库.**至少有69个人从来没有以任何规模工作或不知道如何大规模数学.
我的第二个答案!
就个人而言,我不希望这两个字段构成复合主键.一个独特的钥匙,绝对.绝对是那个唯一键上的聚集索引.但我也将某种非复合身份作为具有非聚集索引的PK.这将允许需要"朋友关系ID"FK的其他表格轻松地绑定到此表格,并且各种触发器可以触发级联事件的友情,诽谤等.

2> 小智..:

看看下面的数据库架构,由Anatoly Lubarsky反向设计:

Facebook架构


这是一个类图,而不是数据库模式
那么每个"用户"都有自己的专用数据库吗?像上面那个?它会如何工作?例如,当用户登录FB检查以查看它是否是有效的User + Pass,然后如果它是有效的facebook会将它们重定向到那个数据库,然后显示来自上述数据库的所有内容

3> burzum..:

TL; DR:

他们使用带有缓存图形的堆栈架构,用于堆栈MySQL底部以上的所有内容.

答案很长:

我自己做了一些研究,因为我很好奇他们如何处理大量数据并快速搜索.我看到人们抱怨定制社交网络脚本在用户群增长时变得缓慢.在我用一万个用户和250万个朋友连接做了一些基准测试后- 甚至没有试图打扰组权限和喜欢和壁挂帖 - 很快就发现这种方法存在缺陷.所以我花了一些时间在网上搜索如何做得更好,并发现这篇官方的Facebook文章:

TAO:Facebook社交图谱的分布式数据存储

TAO:图的力量.

真的建议你在继续阅读之前观看上面第一个链接的演示.这可能是FB在你能找到的幕后工作方式的最佳解释.

视频和文章告诉你一些事情:

他们在堆栈的最底层使用MySQL

SQL DB 上方有TAO层,它至少包含两个级别的缓存,并使用图形来描述连接.

我找不到他们实际用于缓存图表的软件/数据库的任何内容

我们来看看这个,朋友关系是左上角:

在此输入图像描述

嗯,这是一张图.:)它没有告诉你如何在SQL中构建它,有几种方法可以做到这一点,但这个网站有很多不同的方法.注意:考虑到关系数据库是它的原因:它被认为存储标准化数据,而不是图形结构.因此它不会像专门的图形数据库那样好.

还要考虑你必须做更复杂的查询,而不仅仅是朋友的朋友,例如当你想要过滤你和朋友的朋友喜欢的给定坐标周围的所有位置时.图表是这里的完美解决方案.

我不能告诉你如何构建它以便它会表现良好但它显然需要一些试验和错误以及基准测试.

这是我失望的测试只是朋友的朋友的调查结果:

数据库架构:

CREATE TABLE IF NOT EXISTS `friends` (
`id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `friend_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

朋友之友查询:

(
        select friend_id
        from friends
        where user_id = 1
    ) union (
        select distinct ff.friend_id
        from
            friends f
            join friends ff on ff.user_id = f.friend_id
        where f.user_id = 1
    )

我真的建议你创建一些包含至少10k用户记录的示例数据,每个用户记录至少有250个朋友连接,然后运行此查询.在我的机器上(i7 4770k,SSD,16GB RAM),该查询的结果是~0.18秒.也许它可以被优化,我不是数据库天才(欢迎提出建议).但是,如果这是线性的,那么对于100k用户来说已经是1.8秒,对于100万用户来说已经是18秒.

对于~10万用户来说,这听起来可能听起来很好但是考虑到你只是抓住了朋友的朋友并且没有做任何更复杂的查询,例如" 只显示朋友的朋友的帖子+如果我允许或不允许,请进行权限检查看到他们中的一些+做一个子查询来检查我是否喜欢他们中的任何一个 ".如果您已经或不喜欢帖子,或者您必须在代码中执行操作,您想让数据库进行检查.还要考虑这不是您运行的唯一查询,并且您在一个或多或少受欢迎的网站上同时拥有多个活动用户.

我认为我的答案回答了Facebook如何很好地设计他们的朋友关系的问题,但很抱歉我无法告诉你如何以一种快速工作的方式实现它.实现社交网络很容易,但确保它表现良好显然不是 - 恕我直言.

我已经开始尝试使用OrientDB进行图形查询并将边缘映射到底层SQL DB.如果我完成它,我会写一篇关于它的文章.



4> belgarionthe..:

我最好的选择是他们创建了一个图形结构.节点是用户,"友谊"是边缘.

保留一个用户表,保留另一个边缘表.然后,您可以保留有关边缘的数据,例如"他们成为朋友的日子"和"已批准的状态"等.


我有一种感觉,你将不得不为这里的一些人解释一下.
我认为一个更有趣的问题是如何坚持如此庞大的结构(我们谈论的是2亿个节点和数十亿个边缘),以便能够轻松搜索和更新.

5> Nathan Koop..:

这很可能是多对多的关系:

朋友列表(表)

user_id -> users.user_id
friend_id -> users.user_id
friendVisibilityLevel

编辑

用户表可能没有user_email作为PK,但可能作为唯一键.

用户(表)

user_id PK
user_email
password


虽然这当然最有意义,但我认为考虑到Facebook拥有多少用户以及每个Facebook用户拥有多少朋友,性能将会非常糟糕.

6> Adrian J. Mo..:

看看这些描述LinkedIn和Digg如何构建的文章:

http://hurvitz.org/blog/2008/06/linkedin-architecture

http://highscalability.com/scaling-digg-and-other-web-applications

还有"大数据:来自Facebook数据团队的观点"可能会有所帮助:

http://developer.yahoo.net/blogs/theater/archives/2008/01/nextyahoonet_big_data_viewpoints_from_the_fac.html

此外,本文还讨论了非关系型数据库以及某些公司如何使用它们:

http://www.readwriteweb.com/archives/is_the_relational_database_doomed.php

您将看到这些公司正在处理数据仓库,分区数据库,数据缓存和其他更高级别的概念,而不是我们大多数人每天都不会处理的问题.或者至少,也许我们不知道我们这样做.

前两篇文章中有很多链接可以为您提供更多的见解.

更新10/20/2014

Murat Demirbas写了一篇摘要

TAO:Facebook社交图的分布式数据存储(ATC'13)

F4:Facebook温暖的BLOB存储系统(OSDI'14)

http://muratbuffalo.blogspot.com/2014/10/facebooks-software-architecture.html

HTH



7> 小智..:

对于用户朋友数据来说,不可能从RDBMS中检索数据,这些数据在一个固定的时间内超过5亿,因此Facebook使用哈希数据库(没有SQL)实现了这一点,并且他们开源了名为Cassandra的数据库.

因此每个用户都有自己的密钥和队列中的朋友详细信息; 要知道cassandra的工作方式:

http://prasath.posterous.com/cassandra-55



8> 小智..:

2013年6月的这篇文章详细介绍了从关系数据库到具有某些数据类型关联的对象的转换.

https://www.facebook.com/notes/facebook-engineering/tao-the-power-of-the-graph/10151525983993920

有一篇较长的论文可在https://www.usenix.org/conference/atc13/tao-facebook's-distributed-data-store-social-graph上找到



9> Malfist..:

你正在寻找外键.基本上你不能在数据库中有一个数组,除非它有自己的表.


示例模式:

    Users Table
        userID PK
        other data
    Friends Table
        userID   -- FK to users's table representing the user that has a friend.
        friendID -- FK to Users' table representing the user id of the friend


为什么选票呢?至少让别人知道你为什么要对它们进行投票.
downvotes应该留下评论为什么.
特别是当它是一个有效的答案,并得到其他答案的回应(虽然我没有从他们复制,当我回答时,那里没有答案)
@TheTXI:我认为对downvotes的评论是礼貌的,特别是对于那些显然不值得的答案,但我也同意不应强制要求评论.
@freak:为什么?在这个网站上投票的整个概念是投票是匿名的.为什么你觉得犯错有权做什么?
那些在非显而易见的答案上匿名投票的人,就是那些担心如果他们发表评论来解释投票,那么他们的浅薄推理会被曝光的人.
推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有