Большой практический пример

Может ли кто-нибудь представить реальный пример того, как данные будут структурированы в Bigtable? Пожалуйста, поговорите с поисковой системой, социальными сетями или любой другой знакомой точкой зрения, которая ясно и прагматично показывает, как класс столбцов row → column → превосходит традиционные нормированные реляционные подходы.

Ответ 1

Чтение оригинальной технической документации Google было полезно:

http://static.googleusercontent.com/external_content/untrusted_dlcp/labs.google.com/en//papers/bigtable-osdi06.pdf

Как это был полный список источников информации о архитектуре данных Google:

http://highscalability.com/google-architecture


Обновление: 11/4/14

Информацию о новой версии PDF-документа PDF можно найти здесь:

http://static.googleusercontent.com/media/research.google.com/en/us/archive/bigtable-osdi06.pdf

Ответ 2

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

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

Это означает, что вы (а не оптимизатор запросов) сами пишете планы запросов.

Это может увеличить производительность запроса, если вы знаете, как это сделать.

Рассмотрим типичный запрос в поисковой системе: найдите верхние 10 страницы со всеми (или некоторыми) словами, включенными, скажем, "конкурс мокрой футболки", заказанный по релевантности (мы просто оставляем для вас простоту близости).

Для этого вам нужно, чтобы все слова были разделены и сохранены в списке для поиска и итерации, упорядоченном (word, relevance, source). Затем вы разбиваете этот список на (3 * ranks) наборы (каждый из которых начинается в начале слов в вашем поисковом запросе с заданным рангом), где ranks - это возможное число или ранги, скажем, 1 - 10; и присоединяем множества на source,.

В реляционной базе данных это будет выглядеть так:

SELECT  w1.source
FROM    ranks r1
JOIN    words w1
ON      w1.word = 'wet'
        AND w1.rank = r1.value
CROSS JOIN
        ranks r2
JOIN    words w2
ON      w2.word = 'shirt'
        AND w2.rank = r2.value
        AND w2.source = w1.source
CROSS JOIN
        ranks r3
JOIN    words w3
ON      w3.word = 'contest'
        AND w3.rank = r2.value
        AND w3.source = w1.source
ORDER BY
        relevance_formula (w1.rank, w2.rank, w3.rank)
LIMIT 10

Это лучше всего выполнить с помощью MERGE JOIN над тремя наборами, разделенными по рангам.

Однако ни один оптимизатор, о котором я знаю, не построит этот план (не считая того, что relevance_formula не может распространяться по отдельным рангам).

Чтобы обойти это, вы должны реализовать свой собственный план запроса: начать вверху каждой пары слов/рангов и просто спуститься со всех трех наборов одновременно, пропуская отсутствующие значения и используя search, а не next, если вы чувствуйте, что будет слишком много, чтобы пропустить в одном из наборов.

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

Если вы разрабатываете веб-сервер кампуса, то запись этих SELECT * в порядке, даже если они выполняются на одну микросекунду дольше, чем они могли бы быть. Но если вы разрабатываете Google, стоит потратить некоторое время на оптимизацию запросов (чистые реляционные системы, обеспечивающие доступ к их данным с помощью SQL, просто не позволят делать).

Такие называемые NoSQL и реляционные базы данных иногда диффундируют друг в друга. Например, Berkeley DB - это хорошо известный механизм хранения NoSQL, который использовался MySQL в качестве его бэкэнд для хранения, чтобы разрешить запросы SQL. И наоборот, HandlerSocket позволяет делать чистые ключевые значения в реляционном хранилище InnoDB с построенной над ним базой данных MySQL.