Facebook database di design?

voti
120

Mi sono sempre chiesto come Facebook ha progettato l'amico <-> relazione utente.

Immagino che la tabella utenti è qualcosa di simile:

user_email PK
user_id PK
password 

Immagino la tabella con i dati dell'utente (sesso, età ecc collegati tramite e-mail all'utente Vorrei assumere).

Come ci si collega a tutti gli amici di questo utente?

Qualcosa come questo?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

Probabilmente no. Poiché il numero di utenti è sconosciuto e si espanderà.

È pubblicato 17/06/2009 alle 20:17
fonte dall'utente
In altre lingue...                            


13 risposte

voti
21

E 'più probabile una relazione molti a molti:

FriendList (tabella)

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

MODIFICARE

La tabella degli utenti probabilmente non ha user_email come PK, forse come una chiave univoca però.

utenti (tabella)

user_id PK
user_email
password
Risposto il 17/06/2009 a 20:20
fonte dall'utente

voti
86

Mantenere un tavolo amico che detiene l'UserID e poi l'UserID di un amico (lo chiameremo friendID). Entrambe le colonne sarebbero chiavi esterne di nuovo al tavolo degli utenti.

esempio un po '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)

Esempio di utilizzo:

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

Ciò mostra che Bob è diventato amico di entrambi Jon e Joe e che Jon è anche amica di Joe. In questo esempio si assume che amicizia è sempre due modi, quindi non sarebbe bisogno di una riga della tabella come (2,1) o (3,2) perché sono già rappresentati nella direzione opposta. Per esempi in cui l'amicizia o altre relazioni non sono esplicitamente a due vie, si avrebbe bisogno di avere anche le righe per indicare il rapporto a due vie.

Risposto il 17/06/2009 a 20:21
fonte dall'utente

voti
31

La mia scommessa migliore è che hanno creato una struttura di grafo . I nodi sono gli utenti e "amicizie" sono bordi.

Mantenere una tabella di utenti, tenere un altro tavolo di spigoli. Poi si può mantenere i dati sui bordi, come "giorno sono diventati amici" e "Stato approvato", ecc

Risposto il 17/06/2009 a 20:21
fonte dall'utente

voti
5

Siete alla ricerca di chiavi esterne. In sostanza non si può avere una matrice in un database a meno che non ha il proprio tavolo.


schema di esempio:

    utenti Tabella
        userID PK
        altri dati
    amici Tabella
        userID - FK al tavolo di utenti che rappresenta l'utente che ha un amico.
        friendID - FK al tavolo degli utenti che rappresenta l'ID utente di un amico
Risposto il 17/06/2009 a 20:22
fonte dall'utente

voti
2

Tenete a mente che le tabelle del database sono progettati per crescere verticalmente (più righe), non orizzontalmente (più colonne)

Risposto il 17/06/2009 a 20:40
fonte dall'utente

voti
15

Date un'occhiata a questi articoli che descrivono come LinkedIn e Digg sono costruiti:

C'è anche "Big Data: Punti di vista del team dati Facebook" che potrebbe essere utile:

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

Inoltre, c'è questo articolo che parla di database non relazionali e come vengono utilizzati da alcune aziende:

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

Vedrete che queste aziende si occupano di data warehouse, database partizionati, caching dei dati e altri concetti di livello superiore rispetto alla maggior parte di noi non trattare con su base giornaliera. O almeno, forse non sappiamo quello che facciamo.

Ci sono un sacco di link sui primi due articoli che dovrebbero dare un po 'più chiaro.

UPDATE 2014/10/20

Murat Demirbas ha scritto una sintesi su

  • TAO: di Facebook file system distribuito per il social graph (ATC'13)
  • F4: Sistema caldo archiviazione BLOB di Facebook (OSDI'14)

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

HTH

Risposto il 17/06/2009 a 22:38
fonte dall'utente

voti
0

Per quanto riguarda le prestazioni di una tabella molti-a-molti, se si dispone di 2 interi a 32 bit che collegano gli ID utente, l'archiviazione dei dati di base per 200.000.000 di utenti in media 200 amici a testa è poco meno di 300 GB.

Ovviamente, si avrebbe bisogno di un po 'di partizionamento e l'indicizzazione e non avete intenzione di tenerlo a memoria per tutti gli utenti.

Risposto il 18/06/2009 a 01:17
fonte dall'utente

voti
44

Date un'occhiata al seguente schema del database, il reverse engineering da Anatoly Lubarsky :

Facebook Schema

Risposto il 13/07/2009 a 17:18
fonte dall'utente

voti
9

Non è possibile recuperare i dati da RDBMS per gli amici degli utenti dei dati per i dati su più di mezzo miliardo in un momento costante in modo Facebook implementato questo utilizzando un database di hash (senza SQL) e opensourced il database chiamato Cassandra.

Quindi, ogni utente ha la propria chiave e gli amici Dettagli in una coda; sapere come funziona cassandra un'occhiata a questo:

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

Risposto il 20/08/2010 a 06:51
fonte dall'utente

voti
4

Il suo un tipo di database grafico: http://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/social-network.html

La sua non è legato ai database relazionali.

Google per database del grafico.

Risposto il 12/04/2011 a 13:06
fonte dall'utente

voti
1

Probabilmente c'è un tavolo, che memorizza l'amico <-> rapporto utente, dire "frnd_list", avendo i campi 'user_id', 'frnd_id'.

Ogni volta che un utente aggiunge un altro utente come un amico, si creano due nuove righe.

Per esempio, supponiamo che il mio id è 'deep9c' e io aggiungo un id 'akash3b' utente debba come il mio amico, poi due nuove righe vengono creati nella tabella "frnd_list" con i valori ( 'deep9c', 'akash3b') e ( 'akash3b ', 'deep9c').

Ora, quando mostra l'amici-list per un particolare utente, un semplice sql farebbe che: "selezionare frnd_id da frnd_list dove user_id =" dove è l'id del utente connesso (memorizzato come una sessione di attributo).

Risposto il 29/10/2011 a 17:59
fonte dall'utente

voti
6

Questo recente post giugno 2013 va in qualche dettaglio in spiegare il passaggio da basi di dati relazionali a oggetti con le associazioni per alcuni tipi di dati.

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

C'è una carta più disponibile presso https://www.usenix.org/conference/atc13/tao-facebook's-distributed-data-store-social-graph

Risposto il 28/06/2013 a 19:07
fonte dall'utente

voti
31

TL; DR:

Essi utilizzano un'architettura stack con grafici cache per tutto sopra il fondo MySQL del loro stack.

Risposta lunga:

Ho fatto qualche ricerca su questo me stesso perché ero curioso come gestire la loro enorme quantità di dati e di ricerca in un modo rapido. Ho visto persone che si lamentano gli script di social network su misura diventando lento quando la base di utenti cresce. Dopo che ho fatto un po 'me stesso benchmarking con solo 10k utenti e 2,5 milioni di amici connessioni - nemmeno provano a preoccuparsi di permessi di gruppo e simpatie e post muro - si è scoperto in fretta che questo approccio è viziata. Così ho trascorso qualche tempo la ricerca sul web su come farlo meglio e sono imbattuto in questo articolo ufficiale di Facebook:

Ho davvero vi consiglio di guardare la presentazione del primo link qui sopra prima di continuare a leggere. E 'probabilmente la migliore spiegazione di come FB lavora dietro le quinte si possono trovare.

Il video e articolo ti dice alcune cose:

  • Stanno usando MySQL per lo fondo del loro stack
  • Sopra lo SQL DB è lo strato Tao, che contiene almeno due livelli di cache e utilizza grafici per descrivere le connessioni.
  • Non ho trovato nulla su ciò che software / DB quello realmente utilizzato per i loro grafici memorizzati nella cache

Diamo uno sguardo a questo, amici in comune sono in alto a sinistra:

entrare descrizione dell'immagine qui

Bene, questo è un grafico. :) E non ti dice come costruire in SQL, ci sono diversi modi per farlo, ma questo sito ha una buona quantità di approcci diversi. Attenzione: Si consideri che un DB relazionale è quello che è: E 'pensato per memorizzare i dati normalizzati, non una struttura grafico. Così non si esibirà buono come un database grafico specializzato.

Considera anche che si deve fare query più complesse che amici di amici, per esempio quando si desidera filtrare tutti i luoghi intorno a un dato di coordinate che tu ei tuoi amici di amici come. Un grafico è la soluzione perfetta qui.

Non posso dirvi come costruire in modo che esso deve svolgere bene ma richiede chiaramente un po 'di tentativi ed errori e benchmarking.

Qui è la mia deludente prova per solo reperti amici degli amici:

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;

Amici di amici di query:

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

Consiglio vivamente di creare alcuni dati di esempio con almeno 10k record utente e ognuno di loro che hanno amici in comune almeno 250 e quindi eseguire la query. Sulla mia macchina (4770k i7, SSD, 16 GB di RAM) il risultato è stato ~ 0,18 secondi per quella query. Forse può essere ottimizzato, io non sono un genio DB (suggerimenti sono i benvenuti). Tuttavia, se questo scale lineari sei già a 1,8 secondi per appena 100k utenti, 18 secondi per 1 milione di utenti.

Questo potrebbe ancora suonare OKish per ~ 100k utenti, ma considerare che solo amici recuperati di amici e non ha fatto alcun query più complessa come " me visualizzare solo i messaggi di amici di amici + fare il check permesso se mi è permesso o non consentito per vedere alcuni di loro + fare una query sub per controllare se mi piaceva nessuno di loro ". Si vuole lasciare che il DB fare il controllo su se v'è piaciuto un post già o no o si dovrà fare nel codice. Considera anche che questa non è l'unica domanda che si esegue e che tu abbia più di utente attivo al tempo stesso su un sito più o meno popolari.

Credo che la mia risposta risponde alla domanda di come Facebook progettato il loro rapporto amici molto bene, ma mi dispiace che io non posso dirvi come implementare in modo che funzionerà veloce. L'implementazione di un social network è facile, ma fare in modo che si comporta bene, non è chiaramente - IMHO.

Ho iniziato a sperimentare con OrientDB a fare il grafico-query e la mappatura miei bordi al DB SQL sottostante. Se mai avere fatto scriverò un articolo su di esso.

Risposto il 26/02/2015 a 00:34
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more