NoSQL против RDBMS: что выбрать?

22 июня 2016, 19:30

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

Читать далее

На LinkedIn бьёт ключом поток информации о миграции с RDBMS на NoSQL, разобраться в которой и принять решение не так просто. Вы с лёгкостью найдёте и уйму статей на тему «Как мы разработали аналитическую платформу», авторы которых просто перегнали базу данных песен и исполнителей в JSON под MongoDB и прикрутили к ней RESTfull-интерфейс. Маркетологи скажут, что это правильный подход, и будут по-своему правы. Но тем, кто хочет разобраться в тонкостях обеих технологий, стоит узнать чуть больше.

Иллюстрация: devops.com.

Вот противоречивый опыт эволюции от RDBMS к NoSQL Джима Скотта. Его проект оперирует базой данных в 200+ таблиц, и основной трудностью для автора является структура базы и её связи. Он возмущается несовершенством реляционной модели и приводит пример новой архитектуры на базе Apache Drill. Если хотя бы частично разобраться в деталях его проекта и посмотреть комментарии, становиться ясно: у автора не хватило сил и времени на реляционную модель, а речь идёт об обычном бардаке в типичной БД. 200 таблиц — вполне себе обычная цифра для RDBMS.

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

«Переход на NoSQL несёт в себе множество преимуществ для разработчиков. Один из них — более гибкая модель данных и свобода от использования жёстких схем. Вы также увидите значительно улучшенную производительность и возможность горизонтального масштабирования слоя данных. Но большинство NoSQL-продуктов находятся на ранних стадиях продуктового цикла. Если такие функциональные возможности, как комплексные соединения или транзакции на несколько документов могут быть смоделированы в приложении, разработчикам, возможно, лучше использовать традиционную RDBMS. А для некоторых проектов лучшим выбором может быть гибридный подход».

Computerworld со ссылкой на ведущих исследователей Дэвида Девитти и Майкла Стонбрейкера утверждает, что RDBMS не только работает куда быстрее MapReduce, но и является гораздо более зрелой технологией. Тест произведён на кластере с более чем сотней одноядерных серверов: «гугловская» инсталляция MapReduce сравнивается c тестовым RDBMS-кластером. Аналитические задачи, по их мнению, будут работать от 3 до 6 раз быстрее с распределённой RDBMS.

Должен отметить, напрямую сравнивать многоликую NoSQL с RDBMS некорректно. Фреймворки по работе с большими данными охватывают алгоритмы оптимизации и хранения документов, файлов, потоковых и бинарных данных, неструктурированные разнотипные документы, которые здравомыслящий архитектор в RDBMS хранить не будет. Поэтому сравнение MapReduce с RDBMS выглядит наиболее корректно.

Самый интересный и познавательный проект, с моей точки зрения — это диссертация Христофуса Хаджигеоргиу, который сравнивает MySQL-кластер с MongoDB-интсталяцией. Используются запросы: SELECT, вложенный SELECT, INNER JOINS & subquery. Из анализа диссертации видно, что производительность обеих баз во многих случаях кардинально не отличается.

Что такое реляционная модель данных?

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

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

Часто пользователи RDBMS забывают либо путают понятие индекса. Завалив сервер данными, они полагаются на индекс, создаваемый самой RDBMS. Важно помнить, что индекс по содержимому таблиц — это не тоже самое, что индекс по взаимоотношениям объектов вашей предметной области. RDBMS не может понимать семантику вашего домена. Реляционная нотация оперирует понятием связных либо несвязных объектов, в то время как анализ неструктурированных документов может находить связи с релевантностью от 0 до 1 и зависит от применяемого алгоритма.

Индекс в RDBMS можно совершенствовать: создавать обратные связи, надстраивать дополнительные таблицы. Это всё может существенно улучшить «перфоманс». Кроме того, при миграции или конвертировании не расходует хранилище. Логические индексы генерируются только на существующих данных, не засоряют реплики и могут «бэкапиться» в виде процедур.

С помощью RDBMS можно легко проектировать метамодели/объекты, как на обычном языке программирования, когда создаётся некая метаинформация об объекте (класс/структура с именами и типом полей), а затем используются инстансы. Например, есть каталог транспортных средств в виде таблиц:

  • Т1. самолёт
  • Т2. автомобиль

У них могут быть следующие свойства: тип ТС, средняя скорость, годовой пробег, производитель и т.д.

В такой базе данных уже нельзя будет изменить форматы таблиц «бесплатно». А можно создать объект с мета-описанием. Таблица MetaPlane определяет базовый объект «самолёт», его свойства. И производная таблица-тип объекта:

Type   Name
MetaPlane
Integer     Min Weight
Integer     Vecale Type
Integer     Cruising Speed
Integer     Annual Mileage
String Brand

 

Type Name
MetaPlane2
Base MetaPlane
String Model
String SubBrand

А потом создать таблицу экземпляров «Самолёты», где MP_1, MP2_1, MP2_2 таблицы со свойствами самолётов:

Plane Instances
С1 MetaPlane MP_1
С2 MetaPlane2 MP2_1
C3 MetaPlane2 MP2_2

 

 

 

 

Как видно из примера, с помощью RDBMS можно легко описывать объектные отношения, имплементировать наследование, реализовывать объектно-ориентированные базы данных, не прибегая к специфическим ООБД. Мне не попадались задачи по нормализации объектных или полиморфных данных, которые я бы не смог описать с помощью реляционной нотации. Но есть задачи, где заставить работать RDBMS сложнее (из соображений оптимизации и перфоманса), чем некую специфичную объектно-ориентированную или Time Series БД.

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

Особенности RDBMS

Поиск

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

Яркий пример того — мелкие и средние интернет-магазины, где пытаешься найти «телефон с двумя сим-картами», а он только может выдать либо «телефон», либо «двумя», либо «симкартами».

Расширяемость

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

В целом оно так и есть, практически все RDBMS рассчитаны на единственный рабочий экземпляр, без какого-то кластерного взаимодействия. Но Oracle, MySQL и MSSQL давно разрабатывают кластерные продукты.

На данный момент успешно функционирует Sharded MySQL и MySQL Cluster, хотя с существенными ограничениями из-за подключения дополнительного хранилища, нюансами с foregn key при распределённых таблицах и ограниченного размера дополнительной базы. Партиции и шарды существуют и для MSSQL, но с ограничениями на количество серверов, репликации и т.д. Эти особенности лучше изучить, прежде чем принимать решения.

Но ведь что такое NoSQL? Это библиотека с алгоритмами хранения и извлечения данных плюс серверная надстройка для кластерного взаимодействия. Во многих случаях программисту придётся иметь дело с серверной логикой, а это значит, что никто нам не мешает пристроить такую же логику к RDBMS и получить RDBMS-кластер. Вообще, я бы не стал отрицать возможность построения RDBMS-кластера и больше бы ориентировался на природу данных и на специфику задачи.

Когда нужно использовать RDBMS?

Для этого нужно помнить, что RDBMS создавалось для сохранения целостности и надёжности транзакций с помощью ACID. А также для менеджмента данных, которые можно нормализовать с помощью трёх нормальных форм, используя декомпозицию.

База жа NoSQL, в свою очередь, оперирует такими хранилищами, как Document Store, Key-Value Store, Graph Databases. Можно ещё добавить сюда Time Series DB, Search Engines, Native XML DB, Wide Column Stores, Event Stores, Navigational DB. Такие базы могут быть ориентированы на оперирование узлами данных с их связями и атрибутами, а не записями и полями. Или несколькими глобальными таблицами, или просто документами. Иногда говорят, что NoSQL не имеет схемы или обладает динамической схемой данных. Ключевой характеристикой такой базы станет способность к горизонтальному раширению (подключению новых кластерных узолов) и работа с репликами. Изначально IBM характеризовало большие данные с помощью 3-V: Velocity, Variety, Volume. Потом добавилось ещё Veracity. Оптимисты уже начинают вводить 5-V и более.

Если немного «приземлиться», можно сказать так. У RDBMS ваши документы будут храниться в виде полей и записей, на которые вы их будете раскладывать. В NoSQL данные часто будут находиться в виде документов JSON или Binary JSON. В отличие от RDBMS, индексирование в NoSQL зависит от формы хранения и происходит с помощью дублирования и автоматизированного парсинга строк/предложений/документов и выделения слов/паттернов/элементов. Это означает, что в RDBMS ваш документ будет разбросан по таблицам, по разным участкам жёсткого диска, что, в худшем случае, при вычитывании его (документа) частями может привести к десятикратному увеличению объёма данных. В NoSQL же документ может храниться полностью, что, при вычитывании нескольких/всех полей небольшого документа, выльется в одну операцию чтения единственного сектора.

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

Стоит ли переходить на NoSQL?

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

В такой ситуации подкупает кажущаяся простота баз данных. Данные могут находиться в файлах, а паттерны будут находить уже процедуры языка программирования, которые поддерживает среда. Императивные запросы куда более привычны для людей, нежели приведение данных к единой стройной модели. И в логике запросов будет прослеживаться всё то же, что можно сделать на обычной базе только с дописанной системой миграции или конвертации, что у специализирующихся на RDBMS команд уже давно считается рутинной операцией.

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

Как понять, стоит ли вам переходить на NoSQL или нет и что для этого нужно?

Чтобы ответить на этот вопрос, сформулируем семь простых правил.

  1. Если у вас всё работает и работает хорошо, то лучше ничего не трогать. Лучшее — враг хорошего.
     
  2. Если ваши данные не вмещаются в базу, и нужно покупать новые лицензии для RDBMS, то можно мигрировать не только на NoSQL но и на PostgreeSQL или MySQL Shard/Cluster.
     
  3. Если ваши данные или часть данных критически важна (аккаунты пользователей, платёжные и финансовые документы и т.д.), то лучше использовать RDBMS.
     
  4. Если ваш массив документов не подвергается предварительной обработке при записи в базу, то можно переходить на NoSQL. Если вы валидируете все поля и значения документов, то они, как правило, должны храниться в RDBMS.
     
  5. Если вам нужен качественный поиск по всем файлам и документам, то не спешите всё переводить в NoSQL. NoSQL может прекрасно сосуществовать с RDBMS. При наличии документов из п.3 избавиться от RDBMS не получится, либо это может быть очень дорогим удовольствием. Но реализовать полноценный поиск по неструктурированным данным можно только в NoSQL.
     
  6. Если речь идёт о поточных данных (логи, события, поиск, скачивание и хранение документов), это NoSQL.
     
  7. Если документы связаны с неким техническим процессом, их создают и заполняют участники этого процесса, то это, скорее всего, RDBMS.

 

 

*Мнение колумнистов может не совпадать с позицией редакции.

Обсуждение