TL; DR:
Utilizan una arquitectura de pila con gráficos en caché para todo lo que está por encima de la parte inferior de MySQL de su pila.
Respuesta larga:
Investigué un poco sobre esto yo mismo porque tenía curiosidad sobre cómo manejan su gran cantidad de datos y los buscan de manera rápida. He visto a personas quejarse de que los scripts de redes sociales personalizados se vuelven lentos cuando crece la base de usuarios. Después de hacer una evaluación comparativa con solo 10k usuarios y 2.5 millones de conexiones de amigos , sin siquiera tratar de preocuparme por los permisos de grupo, los me gusta y las publicaciones en el muro, rápidamente resultó que este enfoque es defectuoso. Así que pasé un tiempo buscando en la web cómo hacerlo mejor y encontré este artículo oficial de Facebook:
Yo realmente recomiendo que ver la presentación del primer eslabón anterior antes de continuar leyendo. Probablemente sea la mejor explicación de cómo funciona FB detrás de escena que puedes encontrar.
El video y el artículo te dicen algunas cosas:
- Están usando MySQL en la parte inferior de su pila
- Encima de la base de datos SQL está la capa TAO que contiene al menos dos niveles de almacenamiento en caché y está usando gráficos para describir las conexiones.
- No pude encontrar nada sobre qué software / DB realmente usan para sus gráficos en caché
Echemos un vistazo a esto, las conexiones de amigos están en la parte superior izquierda:
Bueno, esto es un gráfico. :) No te dice cómo construirlo en SQL, hay varias formas de hacerlo, pero este sitio tiene una buena cantidad de enfoques diferentes. Atención: considere que una base de datos relacional es lo que es: se cree que almacena datos normalizados, no una estructura gráfica. Por lo tanto, no funcionará tan bien como una base de datos gráfica especializada.
También considere que tiene que hacer consultas más complejas que solo amigos de amigos, por ejemplo, cuando desea filtrar todas las ubicaciones alrededor de una coordenada dada que les guste a usted y a sus amigos de amigos. Un gráfico es la solución perfecta aquí.
No puedo decirte cómo construirlo para que funcione bien, pero claramente requiere algo de prueba y error y evaluación comparativa.
Aquí está mi prueba decepcionante para solo encontrar amigos de amigos:
Esquema DB:
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;
Consulta de amigos de amigos:
(
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 le recomiendo que cree algunos datos de muestra con al menos 10k registros de usuario y cada uno de ellos tenga al menos 250 conexiones de amigos y luego ejecute esta consulta. En mi máquina (i7 4770k, SSD, 16 gb de RAM) el resultado fue ~ 0.18 segundos para esa consulta. Tal vez se pueda optimizar, no soy un genio de DB (las sugerencias son bienvenidas). Sin embargo, si esto escala lineal, ya tiene 1,8 segundos para solo 100k usuarios, 18 segundos para 1 millón de usuarios.
Esto todavía puede sonar aceptable para ~ 100k usuarios, pero tenga en cuenta que acaba de buscar amigos de amigos y no realizó ninguna consulta más compleja como " mostrarme solo publicaciones de amigos de amigos + hacer la verificación de permisos si estoy permitido o NO permitido para ver algunos de ellos + hacer una subconsulta para verificar si me gustó alguno de ellos ". Desea permitir que la base de datos verifique si ya le gustó una publicación o no, o tendrá que hacerlo en código. También considere que esta no es la única consulta que ejecuta y que tiene un usuario más que activo al mismo tiempo en un sitio más o menos popular.
Creo que mi respuesta responde a la pregunta de cómo Facebook diseñó muy bien su relación de amigos, pero lamento no poder decirle cómo implementarla de una manera que funcione rápidamente. Implementar una red social es fácil, pero asegurarse de que funcione bien claramente no lo es, en mi humilde opinión.
Comencé a experimentar con OrientDB para hacer consultas gráficas y asignar mis bordes a la base de datos SQL subyacente. Si alguna vez lo hago, escribiré un artículo al respecto.