Diseño de base de datos de Facebook?

votos
120

Siempre me he preguntado cómo Facebook diseñó la relación de usuario amigo <->.

Me imagino que la tabla de usuarios es algo como esto:

user_email PK
user_id PK
password 

Calculo la tabla con los datos del usuario (sexo, edad, etc. conectados a través del correo electrónico del usuario, supongo).

¿Cómo conecta a todos los amigos con este usuario?

¿Algo como esto?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

Probablemente no. Porque la cantidad de usuarios es desconocida y se expandirá.

Publicado el 17/06/2009 a las 20:17
fuente por usuario
En otros idiomas...                            


13 respuestas

votos
21

Lo más probable es una relación de muchos a muchos:

FriendList (mesa)

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

EDITAR

La tabla de usuarios probablemente no tenga user_email como PK, posiblemente como una clave única.

usuarios (tabla)

user_id PK
user_email
password
Respondida el 17/06/2009 a las 20:20
fuente por usuario

votos
86

Mantenga una tabla de amigos que contenga el UserID y luego el UserID del amigo (lo llamaremos FriendID). Ambas columnas serían claves externas a la tabla Usuarios.

Ejemplo algo útil:

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)

Ejemplo de uso:

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

Esto demostrará que Bob es amigo de Jon y Joe y que Jon también es amigo de Joe. En este ejemplo, asumiremos que la amistad siempre es de dos maneras, por lo que no necesitaría una fila en la tabla como (2,1) o (3,2) porque ya están representadas en la otra dirección. Para ejemplos donde la amistad u otras relaciones no son explícitamente bidireccionales, también necesitaría tener esas filas para indicar la relación bidireccional.

Respondida el 17/06/2009 a las 20:21
fuente por usuario

votos
31

Mi mejor opción es que hayan creado una estructura de gráfico . Los nodos son usuarios y las "amistades" son bordes.

Mantenga una tabla de usuarios, mantenga otra tabla de bordes. Luego puede guardar datos sobre los bordes, como "día en que se hicieron amigos" y "estado aprobado", etc.

Respondida el 17/06/2009 a las 20:21
fuente por usuario

votos
5

Está buscando claves externas. Básicamente, no puede tener una matriz en una base de datos a menos que tenga su propia tabla.


Esquema de ejemplo:

    Tabla de usuarios
        ID de usuario PK
        otros datos
    Mesa de Amigos
        userID: FK en la tabla de los usuarios que representa al usuario que tiene un amigo.
        friendID - FK en la tabla de usuarios que representa la identificación de usuario del amigo
Respondida el 17/06/2009 a las 20:22
fuente por usuario

votos
2

Tenga en cuenta que las tablas de la base de datos están diseñadas para crecer verticalmente (más filas), no horizontalmente (más columnas)

Respondida el 17/06/2009 a las 20:40
fuente por usuario

votos
15

Eche un vistazo a estos artículos que describen cómo se crean LinkedIn y Digg:

También hay "Big Data: puntos de vista del equipo de datos de Facebook" que pueden ser útiles:

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

Además, hay un artículo que habla sobre bases de datos no relacionales y cómo las utilizan algunas empresas:

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

Verá que estas empresas se ocupan de almacenes de datos, bases de datos particionadas, almacenamiento en memoria caché de datos y otros conceptos de nivel superior de los que la mayoría de nosotros nunca manejamos a diario. O al menos, tal vez no sepamos que sí.

Hay muchos enlaces en los primeros dos artículos que deberían darle más información.

ACTUALIZACIÓN 20/10/2014

Murat Demirbas escribió un resumen sobre

  • TAO: almacén de datos distribuidos de Facebook para el gráfico social (ATC'13)
  • F4: el cálido sistema de almacenamiento BLOB de Facebook (OSDI'14)

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

HTH

Respondida el 17/06/2009 a las 22:38
fuente por usuario

votos
0

Con respecto al rendimiento de una tabla de muchos a muchos, si tiene 2 entradas de 32 bits que enlazan las identificaciones de usuario, su almacenamiento de datos básico para 200,000,000 de usuarios con un promedio de 200 amigos cada uno es de menos de 300GB.

Obviamente, necesitarías algunas particiones e índices, y no vas a mantener eso en la memoria para todos los usuarios.

Respondida el 18/06/2009 a las 01:17
fuente por usuario

votos
44

Eche un vistazo al siguiente esquema de base de datos, diseñado por Anatoly Lubarsky :

Esquema de Facebook

Respondida el 13/07/2009 a las 17:18
fuente por usuario

votos
9

No es posible recuperar los datos de RDBMS para los amigos de los usuarios de datos para los datos que atraviesen más de la mitad de un mil millones a la vez de manera constante Facebook implementó esta usando una base de datos de hash (sin SQL) y opensourced la base de datos llamada Cassandra.

Por lo que cada usuario tiene su propia clave y los detalles de amigos en una cola; saber cómo funciona la cassandra vistazo a esto:

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

Respondida el 20/08/2010 a las 06:51
fuente por usuario

votos
4

Es un tipo de base de datos de gráfico: http://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/social-network.html

Su no relacionados con bases de datos relacionales.

Google para bases de datos de gráficos.

Respondida el 12/04/2011 a las 13:06
fuente por usuario

votos
1

Probablemente hay una mesa, que almacena el amigo <-> relación con el usuario, por ejemplo "frnd_list", que tiene campos de los user_id ', 'frnd_id'.

Cada vez que un usuario añade otro usuario como amigo, se crean dos nuevas filas.

Por ejemplo, supongamos que mi id es 'deep9c' y añadir un id 'akash3b' usuario tenga como mi amigo, entonces dos nuevas filas se crean en la tabla "frnd_list" con los valores ( 'deep9c', 'akash3b') y ( 'akash3b ', 'deep9c').

Ahora cuando se muestra la lista de amigos, a un usuario en particular, un SQL sencilla haría que: "seleccionar frnd_id de frnd_list donde user_id =" ¿dónde está el identificador del usuario conectado (guardado como un atributo de sesión).

Respondida el 29/10/2011 a las 17:59
fuente por usuario

votos
6

Este recientes fue junio después de 2013 entra en algunos detalles a explicar la transición de las bases de datos de relación de objetos con las asociaciones para algunos tipos de datos.

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

Hay un papel más largo disponible en https://www.usenix.org/conference/atc13/tao-facebook's-distributed-data-store-social-graph

Respondida el 28/06/2013 a las 19:07
fuente por usuario

votos
31

TL; DR:

Ellos usan una arquitectura de pila con gráficos almacenados en caché para todo, por encima de la parte inferior de MySQL de su pila.

Respuesta larga:

Hice algunas investigaciones en este mismo porque tenía curiosidad cómo manejan su enorme cantidad de datos y la búsqueda de una manera rápida. He visto a gente quejándose de secuencias de comandos de redes sociales a medida convertirse lento cuando el número de usuarios crece. Después hice un poco de la evaluación comparativa de mí mismo con sólo 10k usuarios y 2,5 millones amigo conexiones - ni siquiera tratan de preocuparse de permisos y gustos de grupos y publicaciones en el muro - que rápidamente resultó que este enfoque es defectuoso. Así que he pasado algún tiempo buscando en la web sobre la manera de hacerlo mejor y me encontré con este artículo oficial de Facebook:

Yo realmente recomiendo que ver la presentación del primer eslabón anterior antes de seguir leyendo. Es probablemente la mejor explicación de cómo FB trabaja detrás de las escenas que se pueden encontrar.

El vídeo y el artículo se explica algunas cosas:

  • Están usando MySQL en la parte inferior de su pila
  • Por encima de la SQL DB no es la capa TAO que contiene al menos dos niveles de almacenamiento en caché y está utilizando gráficos para describir las conexiones.
  • No pude encontrar nada de qué software / DB que realmente utilizan por sus gráficos en caché

Vamos a echar un vistazo a esto, amigos conectados son parte superior izquierda:

introducir descripción de la imagen aquí

Bueno, esto es una gráfica. :) No te dice cómo construirlo en SQL, hay varias maneras de hacerlo, pero este sitio tiene una buena cantidad de diferentes enfoques. Atención: Tenga en cuenta que una base de datos relacional es lo que es: Se piensa para almacenar datos normalizados, no una estructura gráfica. Para que no se realice tan bueno como una base de datos gráfica especializada.

También considere que usted tiene que hacer consultas más complejas que amigos de amigos, por ejemplo cuando se desea filtrar todos los lugares en torno a una coordenada dada que usted y sus amigos de amigos como. Un gráfico es la solución perfecta aquí.

No puedo decirle cómo construir de modo que tenga un buen rendimiento pero requiere claramente un poco de ensayo y error y la evaluación comparativa.

Aquí está mi decepcionante prueba para sólo hallazgos amigos de amigos:

DB esquema:

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;

Amigos de Amigos de consulta:

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

Realmente recomiendo que usted cree que algunos datos de la muestra con al menos 10k registros de usuarios y cada uno de ellos tiene por lo menos 250 amigos conectados y luego ejecutar esta consulta. En mi máquina (4770k i7, SSD, 16 GB de RAM) el resultado fue ~ 0,18 segundos para esa consulta. Tal vez se puede optimizar, no soy un genio DB (sugerencias son bienvenidos). Sin embargo, si esta escalas lineales ya se encuentra a 1.8 segundos por sólo 100 mil usuarios, 18 segundos para 1 millón de usuarios.

Esto todavía puede sonar OKish de ~ 100 mil usuarios pero tenga en cuenta que sólo amigos inverosímiles de amigos y no hizo ninguna consulta más compleja como " Me mostrar sólo los mensajes de amigos de amigos + hacer la comprobación de permisos si se me permite o no se permite a ver algunos de ellos + hacer una consulta sub para comprobar si me gustaba ninguno de ellos ". Desea que el PP haga la comprobación de si le gusta un puesto ya o no, o que tendrá que hacer en el código. Ten en cuenta también que esta no es la única consulta se ejecuta y que el tener más de usuarios activos al mismo tiempo en un sitio más o menos popular.

Creo que mi respuesta responde a la pregunta de cómo Facebook ha diseñado su relación amigos muy bien pero me siento que no puedo decir cómo implementar de una manera que va a funcionar rápidamente. La implementación de una red social es fácil, pero asegurándose de que no funciona bien es claramente - en mi humilde opinión.

He comenzado a experimentar con OrientDB que ver el gráfico-consultas y la cartografía de mis bordes de la base de datos SQL subyacente. Si alguna vez se haga voy a escribir un artículo sobre él.

Respondida el 26/02/2015 a las 00:34
fuente por usuario

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