NoSQL подход к хранению данных

Рассмотрим NoSQL-подход, как отказ от реляции, не вдаваясь в детали. Другими словами, упразднение свойства нормальной формы.

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

Что это можеть дать?

  • :+: уменьшение сложности
  • :+: ускорение разработки

Хранение типичного заказа классически выглядит как связка таблиц заказы + позиции_заказов + отношение один-ко-многим. Применив подход NoSQL, а именно отказавшись от реляции, вполне возможно обойтись одной таблицей orders, дополнив ее детальной информацией о товарах, например, в виде JSON. Конечно, это смахивает на NoSQL over SQL =)

Плюсы:

  • :+: существенно упрощает схему БД: прощай JOIN, лишние столбцы (лишние таблицы?)
  • :+: при выводе детальной информации нет надобности писать дополнительный код, детализирующий позицию (название, категория, и т.п.)
  • :+: делает «снимок» товара, как он выглядел в момент покупи - по аналогии с Алиэкспресс: цена соответствует той, что была в момент покупки, решение проблемы удаления товаров из таблицы позиции
  • :+: кидаем в заказ неучтенные при первоначальном проектировании фишки

Минусы:

  • :-: необходима переработка админки
  • :-: потеря реляции, и все то, что это сулит (в частности, поиск)

Решение проблемы поиска по сериализованным данным (NoSQL) в MySQL:

  • поиск через Sphinx (xmlpipe2 - для сериализованных, JSON)
  • через LIKE '%item%', если документов мало, или вначале идет сужение выборки (поиск по корзине определенного клиента)
  • мап-редукция на PHP =) - если размер выборки небольшой (или, опять же, вначале фильтр по клиенту)
- Вы, молодые, всегда против всего! Есть у вас хоть что-то "за"?
- Да, NoSQL!

Рассмотрим типичный проект, находящийся несколько лет на поддержке. В позиции_заказов дополнительно хранятся некоторые поля (название, цена, картинка, артикул) - то есть отношение (relation) к таблице позиции как бы есть, но как бы мы не доверяем той свеженькой информации по товарам, что регулярно обновляются, предпочитая доставать ее из закромов. До свидания, реляция, и это - не единственный пример.

Как составляли резюме:
- У тебя есть хоть какой-то опыт в SQL?
- Нет.
- Не важно. Пиши "Эксперт в NoSQL".

Что это действительно дало?

На практике я использовал хранение данных в виде JSON. При поступлении новой задачи мне развязала руки:

  • :+: в корзину кидаются не предусмотренные ранее атрибуты товара (и не пришлось перелопачивать код)
  • :+: в заказ сохранил не предусмотренную скидку, и не нужно добавлять новый столбец в БД

Пример: корзина товаров

Думаете много столбцов - это не проблема?

Чуть менее ста столбцов пришлось бы создать для страницы выбора инвестиционных площадок на одном сайте. И писать хороший парсер с сотней регулярок (в худшем случае), чтобы базу эту забить. Причем учесть возможные несоответствия между разными документами о площадках - от ошибок, до разного набора данных. Это именно тот пример, когда известная шутка «NoSQL? No, SQL!» работает с точностью наоборот.

Итак, задача была сделана куда быстрее средствами jQuery, который попросту прочесал документы

$('table').each() ... $(this).find('tr').each()

и кинул в консоль JSON, который я прибил к каждой площадке, а в админку запилил простой JSON-редактор.

Как перевести документ MSWord из DOC в JSON

Три администратора баз данных зашлив в бар "NoSQL", но вскоре покинули его, потому что не смогли найти "table".

Резюме

Отказываться от реляции в том, «хорошем», виде, котором мы ее знаем, не следует. Однако стоит дважды подумать о модели данных, и способе их использования.

Хранение сериализованных данных в том или ином виде в MySQL - не новость (вспомним как хранится часть свойств материалов CMS Joomla).

А вопрос использования NoSQL - во многом вопрос веры :)