NoSQL поверх SQL
Рассмотрим 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 - во многом вопрос веры :)