Conception de la base de données Facebook?

je me suis toujours demandé comment Facebook avait conçu la relation ami-utilisateur.

je suppose que la table d'utilisateur est quelque chose comme ceci:

user_email PK
user_id PK
password 

Je chiffre le tableau avec les données de l'utilisateur (sexe, âge, etc connectés via le courrier électronique de l'utilisateur, je suppose).

comment connecte-t-il tous les amis à cet utilisateur?

quelque chose comme ça?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

probablement pas. Parce que le nombre d'utilisateurs est inconnu et va se développer.

123
demandé sur Mike Sherrill 'Cat Recall' 2009-06-17 23:17:39

13 réponses

tenir une table d'ami qui tient L'UserID puis L'UserID de l'ami (nous l'appellerons Friend). Les deux colonnes seraient des clés étrangères de retour à la table des utilisateurs.

exemple assez utile:

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)

Exemple D'Usage:

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

cela montrera que Bob est ami à la fois avec Jon et Joe et que Jon est aussi ami avec Joe. Dans cet exemple, nous supposerons que l'amitié est toujours de deux façons, de sorte que vous n'aurait pas besoin d'une ligne dans la table tels que (2,1) ou (3,2) parce qu'ils sont déjà représentés dans l'autre sens. Pour les exemples où l'amitié ou d'autres relations ne sont pas explicitement bidirectionnelles, vous devez aussi avoir ces lignes pour indiquer la relation bidirectionnelle.

87
répondu TheTXI 2009-06-17 19:33:27

regardez le schéma de base de données suivant, reverse engineered by Anatoly Lubarsky :

Facebook Schema

46
répondu Brad Larson 2013-12-21 17:21:54

TL; DR:

ils utilisent une architecture de pile avec des graphiques en cache pour tout ce qui se trouve au-dessus du bas de leur pile MySQL.

Longue Réponse:

j'ai fait quelques recherches sur ce moi-même parce que j'étais curieux de savoir comment ils gèrent leur énorme quantité de données et la recherche d'une manière rapide. J'ai vu des gens se plaindre des scripts de réseaux sociaux faits sur mesure devenant lents lorsque l'utilisateur la base de pousse. Après que j'ai fait quelques benchmarking moi - même avec juste 10k utilisateurs et 2,5 millions d'amis connexions - sans même essayer de se soucier des permissions de groupe et aime et les poteaux de mur-il s'est vite avéré que cette approche est défectueuse. J'ai donc passé un certain temps à chercher sur le web pour savoir comment faire mieux et je suis tombé sur cet article officiel de Facebook:

je vraiment vous recommandons de regarder la présentation du premier lien ci-dessus avant de continuer la lecture. C'est probablement la meilleure explication du fonctionnement de FB dans les coulisses.

la vidéo et l'article vous disent quelques choses:

  • ils utilisent MySQL à la très bas de leur pile
  • au-dessus de le DB SQL il y a la couche TAO qui contient au moins deux niveaux de cache et utilise des graphiques pour décrire les connexions.
  • je ne pouvais pas trouver quoi que ce soit sur ce logiciel / base de données qu'ils utilisent pour leur mise en cache des graphiques

jetons un coup d'oeil à ceci, les liens d'amis sont en haut à gauche:

enter image description here

C'est un graphique. :) Il ne vous dit pas comment pour le construire en SQL, il ya plusieurs façons de le faire, mais ce site a une bonne quantité d'approches différentes. Attention: considérez qu'un DB relationnel est ce qu'il est: il est pensé pour stocker des données normalisées, pas une structure de graphe. Il ne fonctionnera donc pas aussi bien qu'une base de données graphique spécialisée.

également considérer que vous devez faire des requêtes plus complexes que les amis des amis, par exemple, quand vous voulez filtrer tous les emplacements autour d'une coordonnée donnée que vous et vos amis des amis aiment. Un graphique est la solution parfaite ici.

Je ne peux pas vous dire comment le construire pour qu'il fonctionne bien, mais il nécessite clairement un essai et d'erreur et de benchmarking.

Voici mon décevant test pour juste résultats amis des amis:

DB Schema:

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;

les Amis de Amis de Requête:

(
        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
    )

je vous recommande vraiment de vous créer quelques données d'échantillon avec au moins 10k d'enregistrements d'utilisateurs et chacun d'eux ayant au moins 250 amis connexions et puis exécuter cette requête. Sur ma machine (i7 4770k, SSD, 16 Go RAM) le résultat était ~0,18 secondes pour cette requête. Peut-être qu'il peut être optimisé, Je ne suis pas un génie de la base de données (les suggestions sont les bienvenues). Cependant, si cette balance linéaire vous êtes déjà à 1.8 secondes pour seulement 100k utilisateurs, 18 secondes pour 1 million d'utilisateurs.

cela pourrait encore sembler OKish pour les utilisateurs ~100k mais considérer que vous venez de chercher des amis d'amis et n'avez pas fait de requête plus complexe comme " m'afficher seulement les messages des amis d'amis + Faire la vérification de permission si je suis autorisé ou pas autorisé voir certains d'entre eux + faire une sous-requête pour vérifier si j'aimais tout d'eux ". Vous voulez laisser le DB faire la vérification sur si vous avez aimé un poste déjà ou pas ou vous aurez à faire en code. Estiment également que ce n'est pas la seule requête que vous, et que vous avez plus d'utilisateurs actifs dans le même temps, sur une plus ou moins populaire site.

je pense que ma réponse répond à la question comment Facebook conçu leur relation d'amis très bien, mais je suis désolé que je ne peux pas vous dire comment pour le mettre en œuvre d'une manière il fonctionnera rapidement. Mettre en place un réseau social est facile, mais s'assurer qu'il fonctionne bien n'est clairement pas - IMHO.

J'ai commencé à expérimenter avec OrientDB pour faire les requêtes graph-et mapper mes bords à la base de données SQL sous-jacente. Si jamais j'ai la chance il fait, je vais écrire un article sur le sujet.

33
répondu burzum 2017-06-20 22:16:08

mon meilleur pari est qu'ils ont créé une structure graphique . Les noeuds sont des utilisateurs et les" amitiés " sont des bords.

garder une table des utilisateurs, garder une autre table des bords. Ensuite, vous pouvez conserver des données sur les bords, comme "le jour où ils sont devenus amis" et "statut Approuvé", etc.

32
répondu belgariontheking 2009-06-17 19:39:33

C'est très probablement une relation de plusieurs à plusieurs:

liste d'amis (tableau)

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

MODIFIER

la table d'utilisateur n'a probablement pas user_email comme PK, peut-être comme une clé unique cependant.

utilisateurs (table)

user_id PK
user_email
password
21
répondu Nathan Koop 2009-06-17 19:26:17

jetez un oeil à ces articles décrivant comment LinkedIn et Digg sont construits:

il y a aussi "Big Data: Points de vue de L'équipe de données Facebook" qui pourrait être utile:

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

aussi, il y a cet article qui parle de bases de données non relationnelles et comment elles sont utilisées par certaines entreprises:

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

vous verrez que ces entreprises traitent avec des entrepôts de données, partitionné les bases de données, la mise en cache de données et d'autres concepts de plus haut niveau que la plupart d'entre nous ne traitent jamais sur une base quotidienne. Ou du moins, peut-être qu'on ne sait pas que c'est le cas.

Il y a beaucoup de liens sur les deux premiers articles qui devraient vous donner quelques plus de perspicacité.

mise à jour 10/20/2014

Murat Demirbas a écrit un résumé sur

  • TAO: Facebook distribué banque de données pour le graphe social (ATC'13)
  • F4: le système de stockage en BLOB chaud de Facebook (OSDI '14)

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

HTH

15
répondu Adrian J. Moreno 2014-10-20 20:46:56

il n'est pas possible de récupérer des données à partir de RDBMS pour des amis Utilisateurs données pour des données qui traversent plus d'un demi-milliard à un moment constant ainsi Facebook a mis en œuvre cela en utilisant une base de données de hachage (pas de SQL) et ils ont ouvert la base de données appelée Cassandra.

ainsi chaque utilisateur a sa propre clé et les amis détails dans une file d'attente; pour savoir comment cassandra fonctionne regardez ceci:

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

9
répondu user362541 2017-06-20 22:22:20

ce récent article de juin 2013 explique en détail la transition des bases de données relationnelles aux objets avec associations pour certains types de données.

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

il y a un papier plus long disponible à https://www.usenix.org/conference/atc13/tao-facebook 's-distributed-data-store-social-graph

6
répondu James Sherwin-Smith 2013-06-28 18:07:40

vous cherchez des clés étrangères. Fondamentalement, vous ne pouvez pas avoir un tableau dans une base de données à moins qu'il n'ait sa propre table.


exemple de schéma:

    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
5
répondu Malfist 2009-06-17 19:36:30

C'est un type de base de données graphique: http://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/social-network.html

ce n'est pas lié aux bases de données Relationnelles.

Google pour les bases de données graph.

4
répondu zain 2011-04-12 12:06:36

garder à l'esprit que les tables de base de données sont conçues pour croître verticalement (plus de lignes), Pas Horizontalement (plus de colonnes)

2
répondu Neil N 2009-06-17 19:40:46

il y a probablement une table, qui stocke la relation utilisateur de l'ami< ->, dites" frnd_list", avec les champs 'user_id','frnd_id'.

Chaque fois qu'un utilisateur ajoute un autre utilisateur comme un ami, deux nouvelles lignes sont créées.

par exemple, supposons que mon id soit 'deep9c' et que j'ajoute un utilisateur ayant l'id 'akash3b' comme ami, alors deux nouvelles lignes sont créées dans la table" frnd_list " avec des valeurs ('deep9c','akash3b') et ('akash3b','deep9c').

Now en montrant la liste d'amis à un utilisateur particulier, un simple sql ferait cela: "sélectionnez frnd_id à partir de frnd_list où user_id=" où est l'id de l'utilisateur connecté (stockés sous une session d'attribut).

1
répondu deep9c 2011-10-29 16:59:57

en ce qui concerne la performance d'une table many-to-many, si vous avez 2 ints de 32 bits reliant les ID d'utilisateur, votre stockage de données de base pour 200 000 000 d'utilisateurs moyenne de 200 amis par pièce est un peu moins de 300 Go.

évidemment, vous auriez besoin de partitionnement et d'indexation et vous n'allez pas garder cela en mémoire pour tous les utilisateurs.

0
répondu Cade Roux 2009-06-18 00:17:02