Жизнь без объединений... понимание и общие практики

StackOverflow https://stackoverflow.com/questions/1532218

Вопрос

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

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

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

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

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

Редактировать: Для некоторых разъяснений, Винко Врсалович сказал:

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

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

Бонусные баллы для тех, кто поймает ссылку на xkcd.

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top