Жизнь без СОБЫТИЙ... понимание и общие практики

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

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

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

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

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

EDIT: Для уточнения, Vinko Vrsalovic сказал:

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

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

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

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


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

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

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

", но разве это не становится дорогим?". Вид. Для загрузки данных требуется некоторое внимание. Тем не менее, не существует большого количества отчетов/анализа. Данные предварительно объединены.

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

Ответ 3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Это позволяет, чтобы данные не были нормализован без проблемы с обновлениями.

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

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

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

Ответ 6

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

Ответ 7

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

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

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