Статьи

Относительное видение Кодда: NoSQL прошел полный круг?

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

Тем не менее, я застрял в один момент времени, я нашел совершенно увлекательным: оригинальная разработка реляционных баз данных. Большая часть NoSQL-движения ощущается как восстание против «устаревших» ощущений реляционных баз данных. Поэтому я подумал, что было бы увлекательно быть противоположностью, копаться в том, какую ценность реляционные базы данных добавили в мир. То, что все думают, очевидно, но никто не понимает.

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

И из этого примените эти уроки к сегодняшним базам данных NoSQL. Сегодняшние базы данных повторяют ошибки прошлого? Или они занимают важную нишу (или оба?).

Первые базы данных

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

векторы весело

База данных бедных

Мы могли бы также добавить «индекс» в конец файла, чтобы помочь нам найти конкретные записи, так же, как мы использовали бы индекс в книге. Здесь индекс говорит нам, что запись «doug» содержит 512 символов в файле, а запись «rick» — 9212 символов в файле.

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

векторы весело

База данных бедных

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

Вы можете себе представить, если бы мы взаимодействовали с этой базой данных, нашей первой реакцией было бы создание довольно примитивного интерфейса — создание чего-то низкоуровневого, о котором говорили только в фильмах и пользователях. К счастью, другие увидели прошлое и поняли, что шаблоны, подобные тем, которые используются в наших прокатах видео и других хранилищах данных, могут быть обобщены — что мы можем абстрагировать понятие «запись» и «владение» в нечто гораздо более мощное. В конце концов это именно то, что сделал Codasyl / DBTG (Task Task Group), создав стандартный язык для создания навигационных и иерархических баз данных и взаимодействия с ними.

Размышляя о нашей модели данных, вы можете создать запись в одной из этих баз данных, используя команду RECORD:

Record Name is USER
   Location Mode is Calc Using username
   Duplicates are not allowed
   username Type character 25
   address Type character 50
   phonenumber Type character 10

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

Set Name is USER-VIDEOS
   Order is Next
   Retention is Mandatory
   Owner is USER
   Member is VIDEO

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

Введите Codd

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

Когда Кодд написал свою статью, он подверг критике базы данных DBTG того дня, когда приложение взаимодействовало с абстракциями баз данных. Низкоуровневые абстракции просочились в пользовательские приложения. Логика приложения стала зависеть от аспектов баз данных: в частности, он приводит три критических замечания:

  1. Зависимости доступа : нам часто нужно переходить от пользователей -> видео, чтобы получить доступ к видео. Логика приложения зависит от того, как записи связаны или агрегированы. Я должен использовать один тип записи, чтобы получить другой тип записи.
  2. Зависимости заказа : Приложения зависят от того, как физически данные хранятся в базе данных. Обратите внимание на строку «ORDER is NEXT» в объявлении Set выше. Это определяет хранилище на основе порядка вставки, поэтому поиск будет, в свою очередь, происходить по порядку индекса.
  3. Зависимости индекса : при доступе к индексам в этих базах данных необходимо указывать индексы базы данных в явном виде по имени.

Кодд предложил обойти эти ограничения, сосредоточившись на конкретной абстракции: отношениях. Отношение — это просто кортеж элементов. Элемент ith каждого кортежа является членом некоторого набора, известного как домен этого элемента. Возможно, домен данного элемента — это набор пользователей, идентификаторы пользователей, возможные фильмы для проката и т. Д. Поэтому для наших видео кортеж может выглядеть так:

 (user=u, address=a, list of movies rented=l)

Или другими словами

 (doug, 1234 Bagby St, [Top Gun 3.99, Terminator 12.99])

Можно интерпретировать это отношение как «означающее» любое количество вещей. Мы могли бы приравнять это к утверждению, что «Даг арендует Top Gun в 3.99, а Терминатор в 12.99» или «Даг живет в 1234 Bagby St».

В дополнение к этому Кодд предлагает идею, известную как нормализация. Кодд касается только основ нормализации в этой первой статье. Достаточно сказать, что одной из важных целей нормализации является создание более плоских и менее избыточных отношений, создание более простых предложений из наших отношений. В нормализации первого порядка Кодда, которую он вводит в своей статье, мы бы предпочли сказать «Даг арендует Top Gun за 3,99» и «Даг арендует Терминатор за 12,99» вместо того, чтобы включать оба предложения в предложение. В отношении отношений это будет выглядеть так:

Users Relations
(user=doug, address=1234 BagbySt)

Movies-Rented Relations
(user=doug, movie=Top Gun, price=3.99)
(user=doug, movie=Terminator, price=12.99)

С более простыми и нормализованными отношениями мы можем использовать новый оператор JOIN Кодда, который может выводить отношения из других, более простых и нормализованных отношений. Это очень сильно. Другими словами, с помощью JOIN мы можем создавать знания из меньших единиц знаний. Например, что если наша база данных содержит следующие отношения:

Peoples Relations
(name=Socrates, Occupation=Philosopher)

Occupation-Characteristic Relations
(Occupation=Philosopher, Characteristics=Drunk)

Мы можем присоединиться к профессии = философ и узнать, что Сократ был пьян! Это здорово, потому что на моем уроке искусственного интеллекта в колледже такого рода «рассуждения» представлены как нечто продвинутое. На самом деле, есть целый язык, Пролог, и вся работа состоит в том, чтобы принимать утверждения о мире и предоставлять вам дополнительные факты. Я должен был выучить все это в AI, когда приземленный SQL был прямо у меня под носом, давая мне инструменты, чтобы узнать все, что я хочу, о мире, который представляли мои отношения!

Итак, теперь, когда мы представили эту модель, давайте подумаем, как она соотносится с критикой Кодда:

  1. Зависимости доступа : как отношения, данные делятся на независимые отношения. Там нет «ссылки» между ними, чтобы следовать.
  2. Зависимости порядка: порядок набора отношений не указан. Наборы в математике не имеют понятия порядка. На практике язык реляционных запросов, такой как SQL, позволяет сортировать по любым критериям
  3. Зависимости индекса : что такое индекс? Эта модель данных не упоминает индексы. Индексы — это, к лучшему или худшему, ручка, которая настраивается в месте, где приложение не взаимодействует с базой данных.

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

На самом деле, это довольно необычное и смелое достижение — утверждать, что «это абстракция, которую мы должны использовать», и сделать это в значительной степени успешным. Было не так уж много ожиданий от изобретения Кодда реляционных баз данных. Это не было, как это принято сегодня, незначительное нововведение по сравнению с предыдущими нововведениями. Вместо этого это было просто видение Кодда. Довольно классная штука!

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

NoSQL — мы прошли полный круг?

Да … в некотором смысле, мы прошли полный круг до дней до SQL. Иерархические хранилища данных, однажды забытые, снова выросли. Они, безусловно, страдают от той же критики, что и Кодд. Они пропускают детали более низкого уровня, зависимости доступа, зависимости порядка и индексы вплоть до пользовательского приложения. Использование баз данных Cassandra требует высокого отношения к первичному ключу строки, используя это и только это для доступа к данным. Это индексы и зависимости доступа. База данных, такая как HBase, будет навязывать зависимости порядка, сохраняя ваши строки, отсортированные по ключу строки, что позволяет / требует от вас учитывать порядок, когда ваше приложение сканирует ключи.

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

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

Короче денормализация воняет!

ОК, Eeeyore

векторы весело

Базы данных сложны

Но денормализация чрезвычайно мощная.

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

Я хочу сказать, что опасно просто брать базу данных с собой, потому что это весело и модно. Вы можете создать много технических долгов для себя. Знаете ли вы, что вы обрабатываете чрезвычайно большой объем одной, достаточно четко определенной «вещи»? Тогда иерархическая модель может стать для вас отличным выбором. У вас есть много разных видов записей, которые связывают воедино, но не обязательно содержат части целого? Реляционное хранилище данных может быть идеальным решением.

С Quepid я начал использовать Redis в качестве основной базы данных. Это было удивительно, потому что у нас было простое хранение рейтингов поисковых запросов / документов. Как только мы начали добавлять учетные записи пользователей с учетными записями пользователей, связанными с множеством проблем поиска, стало ясно, что Redis не очень хорош в этом. Мой код начал выглядеть как псевдо-реляционная база данных поверх Redis. Так что я работаю сейчас (а не через год), чтобы перейти на FoundationDB . FoundationDB отлично подойдет для моей задачи, потому что я могу смешивать разные типы моделей в одной базе данных, сохраняя как иерархические рейтинги для документов, так и для реляционных пользователей.

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

Вам нужна помощь в выборе правильного хранилища данных для вашего приложения? Связаться с нами! , Мы можем помочь тебе! У вас есть отзывы к этой статье? Я хотел бы услышать, что вы хотите сказать или критиковать, и узнать больше об истории базы данных! Поэтому, пожалуйста, оставьте комментарий.