Facebook database-ontwerp?

stemmen
120

Ik heb me altijd afgevraagd hoe Facebook ontwierp de vriend <-> gebruiker relatie.

Ik denk de gebruiker tafel is ongeveer als volgt:

user_email PK
user_id PK
password 

Ik denk de tafel met gegevens van de gebruiker (geslacht, leeftijd, enz aangesloten via gebruiker e-mail ik neem aan).

Hoe werkt het allemaal de vrienden om deze gebruiker aan te sluiten?

Iets zoals dit?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

Waarschijnlijk niet. Omdat het aantal gebruikers is onbekend en zal uitbreiden.

De vraag is gesteld op 17/06/2009 om 20:17
bron van user
In andere talen...                            


13 antwoorden

stemmen
21

Het is zeer waarschijnlijk een many to many relatie:

Vriendenlijst (tabel)

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

BEWERK

De gebruiker tafel waarschijnlijk niet user_email te hebben als een PK, misschien als een unieke sleutel wel.

gebruikers (tabel)

user_id PK
user_email
password
antwoordde op 17/06/2009 om 20:20
bron van user

stemmen
86

Houd een vriend tabel waarin de ID en vervolgens de gebruikers-ID van de vriend houdt (we zullen noemen het FriendID). Beide kolommen zou buitenlandse sleutels terug naar de gebruikers tabel.

Enigszins bruikbaar voorbeeld:

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)

Voorbeeld:

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

Dit zal laten zien dat Bob is bevriend met zowel Jon en Joe en dat Jon is ook vrienden met Joe. In dit voorbeeld gaan we ervan uit dat de vriendschap is altijd op twee manieren, dus je zou niet een rij in de tabel zoals (2,1) of (3,2) nodig hebben, omdat ze al in de andere richting zijn vertegenwoordigd. Voor voorbeelden waarbij vriendschap of andere relaties zijn niet expliciet in twee richtingen, zou je nodig hebt om ook die rijen aan de twee-weg relatie aan te geven.

antwoordde op 17/06/2009 om 20:21
bron van user

stemmen
31

Mijn beste gok is dat ze creëerde een grafische structuur . De knooppunten zijn gebruikers en "vriendschappen" zijn randen.

Houd een lijst van de gebruikers, houden een andere tafel van randen. Dan kunt u gegevens te bewaren over de randen, zoals "de dag werden ze vrienden" en "erkende status," etc.

antwoordde op 17/06/2009 om 20:21
bron van user

stemmen
5

Je bent op zoek naar buitenlandse sleutels. In principe kun je niet een array in een database te hebben, tenzij het heeft zijn eigen tafel.


Voorbeeld schema:

    gebruikers Table
        userID PK
        andere gegevens
    vrienden Table
        userID - FK aan tafel de gebruikers van die de gebruiker die een vriend heeft.
        friendID - FK tabel gebruikers die de gebruikers-ID van de vriend
antwoordde op 17/06/2009 om 20:22
bron van user

stemmen
2

Houd in gedachten dat de database tabellen zijn ontworpen om verticaal (meer rijen) groeien, niet horizontaal (meer kolommen)

antwoordde op 17/06/2009 om 20:40
bron van user

stemmen
15

Neem een ​​kijkje op deze artikelen wordt beschreven hoe LinkedIn en Digg zijn gebouwd:

Er is ook "Big Data: Standpunten van de Facebook-Data Team" die nuttig zou kunnen zijn:

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

Ook is er in dit artikel dat de gesprekken over niet-relationele databases en hoe ze worden gebruikt door sommige bedrijven:

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

U zult zien dat deze bedrijven te maken hebben met data warehouses, gepartitioneerd databases, data caching en andere hoger niveau concepten dan de meesten van ons nooit omgaan met op een dagelijkse basis. Of in ieder geval, misschien kunnen we niet weten wat we doen.

Er zijn een heleboel links op de eerste twee artikelen die u wat meer inzicht moet geven.

UPDATE 2014/10/20

Murat Demirbas schreef een samenvatting op

  • TAO: Facebook gedistribueerde data op te slaan voor de sociale grafiek (ATC'13)
  • F4: Facebook's warm BLOB opslagsysteem (OSDI'14)

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

HTH

antwoordde op 17/06/2009 om 22:38
bron van user

stemmen
0

Ten aanzien van de prestaties van een many-to-many tafel, als je 2 32-bit integers koppelen van gebruikers-ID's, uw basis gegevensopslag voor 200.000.000 gebruikers van gemiddeld 200 vrienden per stuk is iets minder dan 300GB.

Uiteraard, zou je een zekere compartimentering en indexering nodig hebt en je bent niet van plan in het geheugen te houden dat voor alle gebruikers.

antwoordde op 18/06/2009 om 01:17
bron van user

stemmen
44

Neem een kijkje op de volgende database schema, reverse engineered door Anatoly Lubarsky :

Facebook Schema

antwoordde op 13/07/2009 om 17:18
bron van user

stemmen
9

Het is niet mogelijk om gegevens van RDBMS voor de gebruiker vrienden van gegevens voor gegevens die over te steken meer dan een half miljard op een constante tijd, zodat Facebook dit geïmplementeerd met behulp van een hash-database (geen SQL) en ze opensourced de database met de naam Cassandra te halen.

Dus iedere gebruiker heeft zijn eigen sleutel en de vrienden Gegevens in een wachtrij; om te weten hoe Cassandra werkt kijken naar dit:

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

antwoordde op 20/08/2010 om 06:51
bron van user

stemmen
4

Het is een type grafiek database: http://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/social-network.html

Het is niet gerelateerd aan relationele databases.

Google voor grafiek databases.

antwoordde op 12/04/2011 om 13:06
bron van user

stemmen
1

Waarschijnlijk is er een tafel, die de vriend slaat <-> gebruiker relatie, zeggen: "frnd_list", met velden 'user_id', 'frnd_id'.

Wanneer een gebruiker een andere gebruiker als een vriend toevoegt, worden er twee nieuwe rijen ontstaan.

Stel bijvoorbeeld dat mijn id is 'deep9c' en voeg ik een gebruiker met id 'akash3b' als mijn vriend, dan twee nieuwe rijen worden gemaakt in de tabel "frnd_list" met de waarden ( 'deep9c', 'akash3b') en ( 'akash3b ', 'deep9c').

Nu bij het weergeven van de vrienden-lijst om een ​​bepaalde gebruiker, zou een eenvoudige sql dat te doen: "te selecteren frnd_id van frnd_list, waar user_id =" waar is de id van de ingelogde gebruiker (opgeslagen als een sessie-attribuut).

antwoordde op 29/10/2011 om 17:59
bron van user

stemmen
6

Deze recente juni 2013 bericht gaat in detail in het uitleggen van de overgang van de relatie databases om objecten met de verenigingen voor bepaalde soorten data.

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

Er is een langer papier verkrijgbaar bij https://www.usenix.org/conference/atc13/tao-facebook's-distributed-data-store-social-graph

antwoordde op 28/06/2013 om 19:07
bron van user

stemmen
31

TL; DR:

Zij maken gebruik van een stapel architectuur met in de cache grafieken voor alles boven de MySQL bodem van hun stack.

Lang antwoord:

Ik deed wat onderzoek op deze mezelf, want ik was benieuwd hoe ze hun enorme hoeveelheid gegevens te verwerken en zoek het op een snelle manier. Ik heb gezien dat mensen klagen over custom made social network scripts steeds traag als het aantal gebruikers groeit. Nadat ik deed wat benchmarking mijzelf met slechts 10k gebruikers en 2,5 miljoen vriend verbindingen - zelfs niet proberen te bekommeren over groepsrechten en voorkeuren en wall posts - het snel bleek dat deze aanpak is gebrekkig. Dus ik heb enige tijd zoeken op het web over hoe het beter te doen en kwam over dit officiële Facebook-artikel:

Ik echt raden u aan de presentatie van de eerste link hierboven voor lees verder kijken. Het is waarschijnlijk de beste uitleg over hoe FB werkt achter de schermen u kunt vinden.

De video- en artikel vertelt u een paar dingen:

  • Ze gebruiken MySQL aan de zeer bodem van hun stack
  • Boven de SQL DB is de BTB laag die ten minste twee niveaus van caching bevat grafieken en gebruikt om de verbindingen te beschrijven.
  • Ik kon niets over welke software / DB ze daadwerkelijk gebruiken voor hun gecachte grafieken vinden

Laten we eens een kijkje op deze, vrienden connecties zijn linksboven:

voer image beschrijving hier

Nou, dit is een grafiek. :) Het maakt je niet vertellen hoe het te bouwen in SQL, zijn er verschillende manieren om het te doen, maar deze site heeft een goed bedrag van de verschillende benaderingen. Opgelet: Bedenk dat een relationele database is wat het is: Men denkt aan het genormaliseerde data, niet een grafische structuur op te slaan. Dus het zal niet zo goed presteren als een gespecialiseerde grafiek database.

Ook van mening dat je meer complexe queries dan alleen vrienden van vrienden, bijvoorbeeld doen als u alle locaties te filteren rond een bepaalde coördinaat die u en uw vrienden van vrienden wilt. Een grafiek is de perfecte oplossing.

Ik kan je niet vertellen hoe het te bouwen zodat het goed zal presteren, maar het vereist duidelijk wat trial and error en benchmarking.

Hier is mijn teleurstellend test voor slechts bevindingen vrienden van vrienden:

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;

Friends of Friends 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
    )

Ik raad u om u enkele voorbeelden van gegevens te maken met ten minste 10k gebruikersrecords en elk van hen hebben ten minste 250 vrienden connecties en voer deze vraag. Op mijn machine (i7 4770k, SSD, 16 GB RAM) was het resultaat ~ 0.18 seconden voor die zoekopdracht. Misschien kan worden geoptimaliseerd, ik ben niet een DB genie (suggesties zijn welkom). Echter, als deze schalen lineair je bent al bij 1,8 seconden voor slechts 100k gebruikers, 18 seconden gedurende 1 miljoen gebruikers.

Dit kan nog steeds klinken OKish voor ~ 100k gebruikers, maar zijn van mening dat je gewoon opgehaald vrienden van vrienden en deden niet meer complexe query als " weer te geven me alleen berichten van vrienden van vrienden + do toestemming controleer ik of ik wel of niet toegestaan om een aantal van hen te zien + doen een sub-query om te controleren of ik vond een van hen ." U wilt laten de DB doen de controle op als je een post vond al of niet of je moet doen in de code. Ook van mening dat dit niet de enige vraag je rennen en dat je meer dan actieve gebruiker op hetzelfde moment op een min of meer populaire site.

Ik denk dat mijn antwoord geeft antwoord op de vraag hoe Facebook ontwierpen hun vrienden relatie heel goed maar het spijt me dat ik je niet kan vertellen hoe het te implementeren op een manier die zal snel werken. Het implementeren van een sociaal netwerk is eenvoudig, maar zorg ervoor dat het goed presteert is duidelijk niet - IMHO.

Ik ben begonnen te experimenteren met OrientDB om de grafiek-queries te doen en in kaart brengen van mijn randen om de onderliggende SQL DB. Als ik ooit het gedaan te krijgen zal ik een artikel over te schrijven.

antwoordde op 26/02/2015 om 00:34
bron van user

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