проектирование баз данных facebook?

голоса
120

Я всегда задавался вопросом, как Facebook разработана друг <-> пользователь отношение.

Я полагаю, что таблица пользователь что-то вроде этого:

user_email PK
user_id PK
password 

Я полагаю, что таблицу с данными пользователя (пол, возраст и т.д., связанных с помощью электронной почты пользователя, я бы предположить).

Как это подключить всех друзей этого пользователя?

Что-то вроде этого?

user_id
friend_id_1
friend_id_2
friend_id_3
friend_id_N 

Возможно нет. Поскольку количество пользователей неизвестно и будет расширяться.

Задан 17/06/2009 в 20:17
источник пользователем
На других языках...                            


13 ответов

голоса
21

Это, скорее всего, многие ко многим:

Список друзей (таблица)

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

РЕДАКТИРОВАТЬ

Таблица пользователей , вероятно , не USER_EMAIL как ПК, возможно , в качестве уникального ключа , хотя.

пользователей (таблица)

user_id PK
user_email
password
Ответил 17/06/2009 в 20:20
источник пользователем

голоса
86

Держи друг таблицу, которая содержит идентификатор пользователя, а затем идент от друга (мы будем называть его FriendID). Обе колонки должны быть внешние ключи обратно к столу пользователей.

Несколько полезный пример:

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)

Пример использования:

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

Это покажет, что Боб дружит как с Джоном и Джо, и Джон также дружит с Джо. В этом примере мы будем считать, что дружба всегда два пути, так что вам не нужна строка в таблице, такие как (2,1) или (3,2), так как они уже представлены в другом направлении. Для примеров, когда дружба или иные отношения, которые явно не два пути, вы должны также иметь те строки, чтобы указать отношения двухсторонних.

Ответил 17/06/2009 в 20:21
источник пользователем

голоса
31

Мой лучший выбор в том , что они создали структуру графа . Узлы пользователей и «дружба» являются ребрами.

Держите одну таблицу пользователей, держать другую таблицу ребер. Затем вы можете сохранить данные о краях, как «день они стали друзьями» и «утвержденный статус» и т.д.

Ответил 17/06/2009 в 20:21
источник пользователем

голоса
5

Вы ищете для внешних ключей. В основном вы не можете иметь массив в базу данных, если она не имеет собственную таблицу.


Пример схемы:

    Таблица пользователей
        идентификатор пользователя ПК
        другие данные
    Друзья Таблица
        идентификатор пользователя - FK в таблице пользователей, представляющих интересы пользователя, у которого есть друг.
        friendID - FK таблице Users', представляющий идентификатор пользователя друга
Ответил 17/06/2009 в 20:22
источник пользователем

голоса
2

Имейте в виду, что таблицы базы данных предназначены расти вертикально (больше строк), а не по горизонтали (больше столбцов)

Ответил 17/06/2009 в 20:40
источник пользователем

голоса
15

Посмотрите на эти статьи, описывающие, как LinkedIn и Digg построены:

Там также «Big Data: Точка зрения от Facebook Team Data», которые могут быть полезны:

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

Кроме того, есть такая статья, которая говорит о том, не реляционных базах данных и как они используются некоторыми компании:

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

Вы увидите, что эти компании имеют дело с хранилищами данных, разбитых на разделы базы данных, кэширование данных и другие концепции более высокого уровня, чем большинство из нас никогда не иметь дело с на ежедневной основе. Или, по крайней мере, может быть, мы не знаем, что мы делаем.

Есть много ссылок на первых двух статей, которые должны дать вам больше понимания.

UPDATE 10/20/2014

Мурат Демирбаш написал резюме на

  • TAO: Facebook, распределенное хранилище данных для социального графа (ATC'13)
  • F4: система теплого хранения BLOB Facebook, (OSDI'14)

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

НТН

Ответил 17/06/2009 в 22:38
источник пользователем

голоса
0

Что касается производительности многие-ко-многим таблице, если у вас есть 2 32-битных Интс связывающих идентификаторы пользователей, ваши основные хранения данных для 200,000,000 пользователей в среднем 200 друзей за штуку просто под 300GB.

Очевидно, что вам потребуется некоторое разбиение и индексации, и вы не собираетесь держать, что в памяти для всех пользователей.

Ответил 18/06/2009 в 01:17
источник пользователем

голоса
44

Взгляните на следующую схему базы данных, обратной инженерии Анатолий Любарского :

facebook Schema

Ответил 13/07/2009 в 17:18
источник пользователем

голоса
9

Это не позволяет извлекать данные из СУБД для пользовательских друзей данных для данных, которые пересекают более полумиллиарда при постоянной времени, поэтому Facebook реализована это с помощью хэш-базы данных (без SQL), и они opensourced базу данных под названием Кассандра.

Таким образом, каждый пользователь имеет свой собственный ключ и друзья деталь в очереди; знать, как Cassandra работ смотрите на это:

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

Ответил 20/08/2010 в 06:51
источник пользователем

голоса
4

Его тип базы данных графа: http://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/social-network.html

Это не связано с реляционными базами данных.

Google для баз данных графа.

Ответил 12/04/2011 в 13:06
источник пользователем

голоса
1

Вероятно, есть таблица, в которой хранятся друг <-> отношение пользователя, скажем, «frnd_list», имея поля «user_id», 'frnd_id.

Всякий раз, когда пользователь добавляет другой пользователь в качестве друга, две новых строки создаются.

Например, предположим, что мой идентификатор «deep9c» и добавить пользователя, имеющего идентификатор «akash3b», как мой друг, тогда две новые строки создаются в таблице «frnd_list» со значениями ( «deep9c», «akash3b») и ( 'akash3b », 'deep9c').

Теперь при показе друзей-список для конкретного пользователя, простой SQL бы сделать это: «выберите frnd_id из frnd_list где user_id =» где идентификатор зарегистрированного пользователя (хранятся в качестве сессионного-атрибута).

Ответил 29/10/2011 в 17:59
источник пользователем

голоса
6

Это последний пост июня 2013 переходит в довольно подробно в объяснении перехода от баз данных отношений к объектам с ассоциациями для некоторых типов данных.

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

Там в более бумаги доступны в https://www.usenix.org/conference/atc13/tao-facebook's-distributed-data-store-social-graph

Ответил 28/06/2013 в 19:07
источник пользователем

голоса
31

TL; DR:

Они используют архитектуру стека кэшированных графиков все выше дна MySQL их стека.

Длинный ответ:

Я сделал некоторые исследования по этому вопросу, потому что самому мне было интересно , как они обрабатывают их огромное количество данных , и искать его в быстром способе. Я видел , что люди жалуются на заказ социальные сети сценариев становится медленной , когда пользовательская база растет. После того как я сделал некоторые бенчмаркинг себя с только 10к пользователей и 2,5 миллиона другу соединений - даже не пытается беспокоиться о правах доступа группы и симпатиях и стенных посты - это быстро оказалось, что этот подход является ошибочным. Так что я провел некоторое время на поиск в Интернете о том , как сделать это лучше и наткнулся на эту статью официальной Facebook:

Я действительно рекомендую вам посмотреть презентацию первой ссылки выше , прежде чем продолжить чтение. Это, вероятно , самое лучшее объяснение того , как работает FB за кулисами вы можете найти.

Видео и статья говорят вам несколько вещей:

  • Они используют MySQL в самом низу их стека
  • Выше в SQL DB есть слой ТАО , который содержит , по меньшей мере , два уровня кэширования и используют графики для описания соединений.
  • Я не мог найти ничего о том, что программное обеспечение / DB они фактически используют для своих кэшированных графиков

Давайте посмотрим на это, друг соединения вверху слева:

введите описание изображения здесь

Ну, это граф. :) Это не говорит вам , как построить его в SQL, есть несколько способов сделать это , но этот сайт имеет хорошее количество различных подходов. Внимание: Учтите , что реляционная БД, что это такое: Считается , хранить нормализованные данные, а не структуру графа. Поэтому он не будет выполнять так же хорошо , как специализированная базу данных графа.

Также считаю, что вы должны делать более сложные запросы, чем просто друзья друзей, например, когда вы хотите, чтобы отфильтровать все места вокруг заданной координаты, что вы и ваши друзья друзей, как. Граф является идеальным решением здесь.

Я не могу сказать вам, как построить его так, что он будет хорошо работать, но это явно требует некоторых проб и ошибок и бенчмаркинга.

Вот мое разочарование тест для всего выводов друзей друзей:

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;

Друзья Друзей запроса:

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

Я очень рекомендую вам создать вам некоторые выборочные данные по крайней мере 10k записей пользователей , и каждый из них имеет , по меньшей мере , 250 соединения друга , а затем запустить этот запрос. На моей машине (i7 4770k, SSD, 16gb RAM) результат был ~ 0,18 секунды для этого запроса. Может быть , это может быть оптимизирован, я не гений DB (предложения приветствуются). Однако, если эти весы линейны вы уже в 1,8 секунде для всего 100k пользователей, 18 секунд , 1 млн пользователей.

Это может звучать по- прежнему OKish для ~ 100k пользователей , но считают , что вы просто надуманные друзья друзей и не делать ничего более сложный запрос , как " отображать меня только посты от друзей друзей + сделать проверку прав доступа , если я разрешено или не разрешено чтобы увидеть некоторые из них + сделать запрос к югу , чтобы проверить , нравится ли мне какие - либо из них ». Вы хотите , чтобы позволить DB сделать чек, если вы понравился пост уже или нет , вы должны сделать в коде. Также считаю , что это не единственный запрос запуска , и что ваш имеют более активного пользователя , в то же время на более или менее популярной.

Я думаю, что мой ответ отвечает на вопрос, как Facebook разработаны их друзья отношения очень хорошо, но мне жаль, что я не могу сказать вам, как осуществить это таким образом, он будет работать быстро. Реализация социальной сети легко, но убедитесь, что он хорошо работает явно не - ИМХО.

Я начал экспериментировать с OrientDB сделать граф-запросы и отображение моих краев к основной БД SQL. Если я когда-нибудь это сделать я напишу статью об этом.

Ответил 26/02/2015 в 00:34
источник пользователем

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