Жизнь без СОЕДИНЕНИЙ ... понимание и общие практики - PullRequest
59 голосов
/ 07 октября 2009

Многие "BAW" (сайты с большими задницами) используют методы хранения и поиска данных, которые опираются на огромные таблицы с индексами, и используют запросы, которые не / не могут использовать JOIN в своих запросах (BigTable, HQL). и т. д.) для решения вопросов масштабируемости и шардинга баз данных. Как это работает, когда у вас есть много-много данных, которые очень связаны?

Я могу только предположить, что большая часть этого объединения должна быть сделана на стороне приложения вещей, но разве это не становится дорогим? Что если вам нужно сделать несколько запросов к нескольким различным таблицам, чтобы получить информацию для компиляции? Разве попадание в базу данных во много раз не становится дороже, чем просто использование объединений? Я думаю, это зависит от того, сколько данных у вас есть?

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

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

Как кто-то сказал ниже, ORM "не работают" без объединений. Существуют ли другие уровни доступа к данным, которые уже доступны разработчикам, работающим с данными на этом уровне?

EDIT: Для некоторого уточнения Винко Врсалович сказал:

"Я верю, что Сникер хочет поговорить о NO-SQL, где транзакционные данные денормализован и используется в Hadoop или Схемы BigTable или Cassandra. "

Это действительно то, о чем я говорю.

Бонусные баллы для тех, кто ловит ссылку на xkcd.

Ответы [ 7 ]

35 голосов
/ 16 октября 2009

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

Если вы начнете расти быстрыми темпами и поймете, что вам придется масштабироваться за пределы размера одного сервера БД, вам неожиданно придется сделать гораздо более трудный выбор. Вам нужно будет начать выявлять узкие места и устранять их. СУБД станет одним неприятным узлом взаимозависимости, который вам придется дразнить. Чем больше взаимосвязаны ваши данные, тем больше работы вам придется выполнить, но, возможно, вам не придется полностью распутывать все это. Если вы интенсивно читаете, возможно, вы сможете обойтись простой репликацией. Если вы насыщаете свой рынок, а его рост выравнивается, возможно, вы сможете частично денормализовать и разделить на фиксированное количество серверов БД. Возможно, у вас есть несколько проблемных таблиц, которые можно переместить в более масштабируемое хранилище данных. Возможно, ваш профиль использования очень удобен для кэширования, и вы можете просто перенести загрузку в гигантский кластер memcached.

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

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

Чтобы ответить на ваш вопрос о том, как часто используемые ORM справляются с невозможностью использования JOIN, краткий ответ: они не . ORM расшифровывается как Object Relational Mapping, и большая часть работы ORM просто переводит мощную реляционную парадигму логики предикатов в простые объектно-ориентированные структуры данных. Большая часть ценности того, что они вам дают, просто не будет возможна из хранилища значений ключей. На практике вам, вероятно, потребуется создать и поддерживать свой собственный уровень доступа к данным, который соответствует вашим конкретным потребностям, потому что профили данных в таких масштабах будут сильно различаться, и я считаю, что слишком много компромиссов для появления инструмента общего назначения и стать доминирующим, как RDBMSs. Короче говоря, вам всегда придется выполнять больше работы в этом масштабе.

Тем не менее, будет определенно интересно посмотреть, какую реляционную или другую агрегированную функциональность можно построить поверх примитивов хранилища значений ключей. У меня на самом деле нет достаточного опыта, чтобы комментировать конкретно, но в корпоративных вычислениях есть много знаний об этом много лет назад (например, Oracle), много неиспользованных теоретических знаний в академических кругах, много практических знаний в Google, Amazon, Facebook и др., Но знания, которые просочились в более широкое сообщество разработчиков, все еще довольно ограничены.

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

21 голосов
/ 07 октября 2009

Вы начинаете с ошибочного предположения.

Хранилище данных не нормализует данные так же, как нормализует приложение транзакции. Там не "много" объединений. Есть относительно немного.

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

Поскольку вам не нужно беспокоиться об обновлениях, вы не разлагаете вещи до уровня 2NF, когда обновление не может привести к аномальным отношениям. Отсутствие обновлений означает отсутствие аномалий; и нет разложения и нет соединений. Вы можете предварительно присоединиться ко всему.

Как правило, данные DW разлагаются в соответствии со звездообразной схемой. Это поможет вам разбить данные на числовые таблицы «фактов», которые содержат показатели - числа с единицами измерения - и ссылки на внешние ключи для измерения.

Измерение (или «бизнес-сущность») лучше всего рассматривать как реальную вещь с атрибутами. Часто это включает в себя такие вещи, как география, время, продукт, клиент и т. Д. Эти вещи часто имеют сложную иерархию. Иерархии обычно произвольны, определяются различными потребностями бизнес-отчетности и не моделируются как отдельные таблицы, а просто столбцы в измерении, используемом для агрегирования.


Чтобы ответить на некоторые ваши вопросы.

"это соединение должно быть сделано на стороне приложения вещей". Вид. Данные «предварительно соединены» перед загрузкой. Данные измерений часто являются объединением соответствующих исходных данных об этом измерении. Он соединен и загружен как относительно плоская структура.

Не обновляется. Вместо обновлений добавляются дополнительные исторические записи.

«но разве это не становится дороже?». Вид. Требуется некоторая осторожность, чтобы загрузить данные. Тем не менее, не так много объединений для отчетности / анализа. Данные предварительно объединены.

Проблемы ORM в значительной степени спорны, поскольку данные предварительно объединены. Ваш ORM соответствует факту или измерению в зависимости от ситуации. За исключением особых случаев, размеры имеют тенденцию быть небольшими и полностью помещаться в памяти. Исключение составляют случаи, когда вы работаете в сфере финансов (банковское дело или страхование) или в коммунальных службах и имеете большие базы данных клиентов. Эти измерения клиентов редко помещаются в память.

14 голосов
/ 07 октября 2009

A JOIN - это чисто реляционный термин, и не все базы данных являются реляционными.

Другие модели баз данных имеют другие способы построения отношений.

В сетевых базах данных используются бесконечные цепочки find a key - fetch the reference - find a key, которые должны программироваться на общем языке программирования.

Код можно запустить на стороне приложения или на стороне сервера, но он не SQL и даже не основан на множестве.

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

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

Это делает обход сетей более быстрым - если вы написали эффективный код для этого.

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

Чтобы найти эти значения в реляционной базе данных, движок должен выполнить следующие действия:

  • Узнайте, где находится кортеж, содержащий первое значение
  • Найти второе значение
  • Найдите адрес корня в B-Tree, содержащем данные, к которым относится второе число
  • Пройдите по этому дереву
  • Найти указатель на фактическую таблицу (которая может быть сохранена как сама B-Tree, в этом случае указатель является значением PRIMARY KEY строки, за которой мы следуем)
  • Найти строку таблицы по указателю или пройти по ней
  • Наконец, получите результат.

И вы можете контролировать это только в определенной степени. После этого вы просто запускаете запрос SQL и ждете.

Реляционная модель, созданная для упрощения жизни разработчика, а не для достижения суперскорости всегда и не смотря ни на что.

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

Возможно, вы захотите прочитать статью в моем блоге

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

4 голосов
/ 07 октября 2009

Когда вы денормализуете свои данные таким образом, вы делаете это, чтобы избежать затрат на объединение разнородных предметов; Вы соглашаетесь с тем, что некоторые данные могут дублироваться и что определенные способы их объединения могут быть затруднены для повышения производительности при использовании простых запросов.

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

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

Такого рода вещи действительно нужны только для действительно массивных наборов данных, и здесь есть все виды компромиссов. Чтобы привести только один пример: BigTable не может выполнять агрегированные запросы, такие как подсчет. С его помощью можно получить примерно точную цифру - в том смысле, что если у вас есть, скажем, 12 149 173 записи, из которых 23 721 было добавлено за последний час, то не имеет большого значения, что лучшее, что вы можете узнать, это у вас есть «около 12 100 000 записей». Если ваше приложение зависит от знания точной цифры в любой данный момент, тогда вам не следует использовать BigTable для этого, это общий подход.

3 голосов
/ 12 октября 2009

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

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

Приложения, такие как Amazon, могут позволить себе загружать все данные для одного пользователя в ОЗУ (насколько велика будет корзина покупок?), Затем обновлять данные в ОЗУ и записывать их как один элемент данных.

Еще раз снимая необходимость иметь большинство данных нормализовано.

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

0 голосов
/ 07 октября 2009

Как правило, хранилище данных строится на основе объединений и данных, разбитых на таблицы измерений и фактов (с так называемыми «звездными схемами» и т. Д.)

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

Мне неизвестны какие-либо инструменты ORM, которые работают с системами баз данных, которые не допускают объединения, поскольку они обычно не рассматриваются как традиционные реляционные базы данных.

0 голосов
/ 07 октября 2009

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

...