2.1 Появление термина NoSQL

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

В конце 90-х появился термин NoSQL. Но правильный смысл этого слова появился только в 2009 году. Раньше NoSQL была опенсорсной базой данных, которая хранила данные в виде ASCII файлов и использовала шелловские скрипты вместо SQL. Но это не имеет ничего общего с тем, как оно используется сейчас.

В конце 90-х появился термин NoSQL. Но правильный смысл этого слова появился только в 2009 году. Раньше NoSQL была опенсорсной базой данных, которая хранила данные в виде ASCII файлов и использовала шелловские скрипты вместо SQL. Но это не имеет ничего общего с тем, как оно используется сейчас.

В июне 2009 года в Сан-Франциско Йоханом Оскарссоном была проведена встреча, в ходе которой было планировалось обсудить новые тенденции в ИТ-рынке хранения и обработки данных. Задача была найти эмоциональный и короткий термин для яркой вывески встречи и подобрать ему Твиттеровский хэштег. Эрик Эванс из RackSpace предложил такой термин — «NoSQL». Этот термин использовался лишь на одну встречу, но несмотря на это, он быстро распространился по мировой сети и стал названием целого направления в ИТ-индустрии. На встрече были представлены Voldemort (клон Amazon Dynamo), Cassandra, Hbase (аналог Google BigTable), Hypertable, CouchDB и MongoDB.

Стоит отметить, что термин "NoSQL" имеет стихийное происхождение и не имеет общепризнанного определения или научного учреждения за спиной. Он отражает направление развития ИТ в сторону от реляционных баз данных. Расшифровывается как Not Only SQL, хотя есть и прямое определение No SQL. Прамод Садаладж и Мартин Фаулер попытались систематизировать знания о NoSQL мире в своей книге "NoSQL Distilled".

2.2 Базовые характеристики NoSQL баз данных

Общие характеристики для всех NoSQL систем мало. Под лэйблом NoSQL прячут много разных систем (полный список на NoSQL Database). Некоторые характеристики присущи только определённым NoSQL базам - я об этом также упомяну.

1. Не используется SQL

Мы говорим про ANSI SQL DML, потому что многие базы данных пытаются использовать query languages, похожие на известный синтаксис. Но никто не смог полностью реализовать его. По слухам, есть стартапы, которые пытаются реализовать SQL, например, Drawn To Scale и hadapt.

2. Неструктурированные (schemaless)

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

Например, при изменении названия поля в MongoDB:


BasicDBObject order =new BasicDBObject();
order.put("date", orderDate); // это поле было давно
order.put("totalSum", total); // раньше мы использовали просто "sum"

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

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


BasicDBObject order =new BasicDBObject();
Double totalSum = order.getDouble("sum"); // Это старая модель
if (totalSum  ==null)
totalSum = order.getDouble("totalSum"); // Это обновленная модель

Когда мы перезапишем, мы запишем это поле в базу данных в новом формате.

Отсутствие схемы дает пользу: мы можем эффективно работать с разреженными данными. Например, если в одном документе есть поле date_published, а в другом нет, то пустое поле date_published для второго не будет создано. Также в NoSQL базах данных мы используем понятия таблиц/колонок. Но из-за отсутствия схемы, колонки не объявляются декларативно и могут меняться/добавляться во время работы. Это позволяет использовать динамические колонки для списков.

У неструктурированных схем есть проблемы: дорогостоящие накладные расходы при изменении модели данных и отсутствие ограничений базы (например, not null, unique, check constraint и т.д.), а также трудности понимания и контроля структуры данных при параллельной работе с базами данных разных проектов (без базовых словарей). Тем не менее, в существующем мире гибкость является достоинством. Например, Twitter пять лет назад хранил небольшое количество дополнительной информации по твитам (время, Twitter handle и метаинформация), а сейчас в базе сохраняется несколько килобайт данных.

2.3. Представление данных в виде агрегатов (aggregates)

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

В этом примере мы показываем агрегаты для реляционной модели e-commerce с заказом, позициями заказа, платежами и продуктом. Заказ и позиции связаны в один логический объект. Каждая позиция хранит информацию о продукте, например название. Это нужно, чтобы избежать запроса продукта при извлечении заказа, что соответствует правилу минимума «джоинов» между объектами.

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

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

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

Cравнить плюсы и минусы обоих подходов можно увидеть в таблице ниже: