Реляционные (SQL) базы — это строгие таблицы со схемой, связи по ключам и транзакции с гарантиями ACID (PostgreSQL, MySQL). NoSQL — общее название для баз с гибкой или отсутствующей схемой, которые жертвуют частью строгости ради масштаба и удобства под конкретную форму данных. NoSQL не один, а несколько семейств: документные (MongoDB), ключ-значение (Redis), колоночные (Cassandra), графовые (Neo4j) — каждое под свой случай. А как моделировать данные под документную базу — в записи про моделирование в NoSQL. CAP-теорема говорит грубое: когда сеть между узлами рвётся, приходится выбирать между согласованностью данных и доступностью сервиса — всё сразу не получится. Рабочее правило: по умолчанию SQL, а NoSQL — осознанно под конкретную задачу, где SQL не тянет.
На одном проекте архитектор выбрал MongoDB, потому что «она гибкая, не надо заранее придумывать схему». Через год данные про деньги — платежи, балансы — расползлись по документам в трёх разных форматах, потому что схему никто не сторожил, и собрать корректный финансовый отчёт стало отдельным адом. Гибкость, за которую брали NoSQL, обернулась тем, что у одинаковых по смыслу записей были разные поля. Это классическая ошибка: выбрать NoSQL не под задачу, а «чтобы было современно».
Цена была вполне конкретной: три формата одной и той же записи о платеже (поле суммы то amount, то sum, то вложенный объект; валюта то отдельным полем, то склеена со строкой) — и каждый квартальный финотчёт превращался в недели ручной работы на то, чтобы свести эти форматы к одному и не потерять ни рубля. Сэкономили на проектировании схемы один спринт — заплатили этим спринтом за каждый отчёт потом. «Схему не сторожили» звучит безобидно, пока это не деньги.
Аналитик не выбирает базу единолично — это решение с архитектором. Но аналитик описывает данные и их связи, а значит должен понимать последствия выбора и уметь сказать «для этих данных нужен SQL, потому что тут деньги и отчётность» или «вот здесь NoSQL уместен». Иначе выбор сделают по моде, а расплачиваться будет бизнес.
Что такое реляционные (SQL) базы
Реляционная база хранит данные в таблицах со строгой схемой: заранее объявлено, какие есть столбцы и какого они типа. Нельзя положить в заказ поле, которого нет в схеме, — база не пустит. Таблицы связаны ключами, а изменения можно объединять в транзакции с гарантиями ACID: «всё или ничего», данные не побьются, согласованность не нарушится. Подробно таблицы, ключи и ACID разобраны в записи про базы данных для аналитика, а как писать выборки — в записи про SQL: SELECT и JOIN; здесь важно одно: SQL-база ценой строгости даёт надёжность и предсказуемость.
Строгая схема — это не ограничение ради ограничения, это сторож. Он не даёт данным «расползтись»: если поле объявлено как сумма-число, туда не запишется строка «примерно тысяча». Для денег, заказов и любых данных, где важна целостность, этот сторож бесценен.
Что такое NoSQL и какой он бывает
NoSQL — это не одна технология и даже не «база без SQL», а зонтичный термин для баз, которые устроены не как реляционные. Их объединяет то, что они отказываются от части строгости (жёсткой схемы, связей, иногда ACID) ради чего-то другого: скорости, масштаба, удобной под конкретную форму данных. И это разные семейства под разные задачи:
| Тип NoSQL | Пример | Когда уместен |
|---|---|---|
| Документные | MongoDB | Данные — самодостаточные документы разной формы (карточки товаров с разным набором характеристик, профили, логи событий). |
| Ключ-значение | Redis | Очень быстрый доступ по ключу: кеш, сессии пользователей, счётчики. Часто живёт рядом с SQL, а не вместо. |
| Колоночные | Cassandra | Огромные потоки записи и масштаб на много серверов: метрики, телеметрия, ленты событий. |
| Графовые | Neo4j | Данные, где главное — связи и пути между ними: соцсети, рекомендации, графы «кто кого знает». |
Обратите внимание: документная база и графовая — это совершенно разные вещи, объединённые только тем, что они «не реляционные». Поэтому фраза «давайте возьмём NoSQL» сама по себе ничего не значит — надо спросить «какой именно и зачем».
Граница давно размыта
Современный PostgreSQL умеет хранить документы (тип JSONB) почти как MongoDB, а многие NoSQL-базы добавили транзакции, которых раньше избегали. Так что «SQL против NoSQL» — это не два враждующих лагеря, а спектр. На практике вопрос звучит не «или-или», а «какую базу под какие данные», и в одной системе их часто несколько: SQL под основные данные, Redis под кеш.
CAP-теорема на пальцах
CAP — три свойства распределённой базы (той, что живёт на нескольких серверах-узлах сразу): Consistency (согласованность — все узлы показывают одни и те же актуальные данные), Availability (доступность — система отвечает на запросы), Partition tolerance (устойчивость к разрыву сети между узлами).
Суть теоремы простыми словами: сеть между серверами рано или поздно рвётся — это не «если», а «когда», поэтому устойчивость к разрыву (P) на деле не выбор, а данность. А вот в момент разрыва приходится выбирать из оставшихся двух. Представьте два узла, которые перестали видеть друг друга, и к одному приходит запрос:
- Выбираем согласованность (CP): узел не уверен, что его данные актуальны (вдруг сосед уже их изменил), поэтому честно отвечает «не могу гарантировать, попробуйте позже». Данные не соврут, но сервис временно недоступен. Так ведут себя базы про деньги.
- Выбираем доступность (AP): узел отвечает тем, что у него есть, даже рискуя отдать слегка устаревшее. Сервис жив и отвечает, но два пользователя на разных узлах на миг могут увидеть разное. Так ведут себя ленты, корзины, лайки.
Перевод на язык решений: где цена неверных данных высока (банк, склад, остатки товара) — выбирают согласованность, пусть иногда ценой «подождите». Где важнее, чтобы сервис всегда отвечал, а лёгкое расхождение на секунды не страшно (соцсеть, каталог) — выбирают доступность. Это и есть тот самый размен, который аналитик должен называть вслух, а не получать случайно.
Strong и eventual: главный размен на практике
CAP описывает поведение только в момент сбоя — когда сеть порвалась. Но размен между согласованностью и скоростью аналитик встречает каждый день, даже когда всё работает. Поэтому важнее CAP знать про модели консистентности — насколько свежие данные гарантирует база при чтении.
- Strong consistency (строгая): любое чтение сразу после записи видит эту запись. Записали баланс — следующий запрос вернёт уже новый. Так ведёт себя обычная SQL-база. Платишь за это тем, что узлам надо договориться, прежде чем ответить.
- Eventual consistency (итоговая): запись доезжает до всех узлов не мгновенно, а через короткое время. Сразу после записи другой узел может вернуть ещё старое значение, но «в конце концов» (eventually) все придут к одному. Так ведут себя AP-базы — отдают «почти свежее» ради скорости и доступности.
Между этими полюсами есть промежуточные гарантии, которые часто и нужны на практике. Самая ходовая — read-your-writes («читай свои записи»): пользователь всегда видит результат своих изменений сразу, даже если для остальных они доедут с задержкой. Поставил аватарку — ты её видишь немедленно, друзья — через секунду. Это и есть честный компромисс: глобальной свежести нет, но персонально для автора изменения система ведёт себя «строго».
CAP — упрощение, точнее PACELC
CAP описывает только случай разрыва сети (Partition). Но PACELC добавляет честную вторую половину: Partition → выбор Availability vs Consistency; Else (в нормальном режиме, без сбоя) → выбор Latency vs Consistency. То есть размен «согласованность против скорости» существует всегда, а не только когда что-то сломалось: чтобы гарантировать строгую свежесть, узлам надо синхронизироваться, и это добавляет задержку. PACELC сформулировал Дэниел Абади в 2010 году именно потому, что CAP молчит про штатную работу. Аналитику не нужно сыпать буквами на собесе, но понимать, что «строгая консистентность стоит latency даже без сбоев», — обязательно.
Зачем это аналитику: формулировка требования «данные должны быть согласованы» — пустая, пока не сказано насколько. «Баланс счёта — strong, видим всегда точную сумму» и «счётчик лайков — eventual, отстал на секунду — не страшно» — это два разных требования к двум разным хранилищам. Назвать модель консистентности по каждому потоку данных — ровно та работа, ради которой аналитик участвует в выборе базы.
Когда SQL, когда NoSQL
Свести к чек-листу. Берите SQL, когда:
- В данных много связей (клиенты — заказы — товары — платежи), и их постоянно надо соединять.
- Есть деньги и транзакции: списания, балансы, оплаты — там, где нужны ACID и «всё или ничего».
- Нужна отчётность: гибкие выборки, агрегаты, JOIN-ы — это родная стихия SQL.
- Данные должны быть целостными и предсказуемыми, а строгая схема — это плюс, а не помеха.
Смотрите в сторону NoSQL, когда:
- Огромный масштаб или поток записи, который один SQL-сервер физически не тянет (метрики, телеметрия, миллионы событий в секунду).
- Данные без жёстких связей и разной формы — самодостаточные документы, где строгая схема только мешает.
- Нужен кеш или очень быстрый доступ по ключу (Redis под сессии и счётчики).
- Вы строите большие потоки событий — это смыкается с асинхронной архитектурой и очередями из записи про синхронную и асинхронную интеграцию: события льются потоком, и колоночная база поглощает их лучше реляционной.
Правило по умолчанию
Если сомневаетесь — берите SQL. Реляционная база покрывает подавляющее большинство бизнес-задач, её знают все, у неё предсказуемое поведение и зрелые инструменты. NoSQL берут под конкретную задачу, когда есть внятный ответ на вопрос «а что именно тут не тянет SQL». «Современно» и «модно» — не ответ. «Нам нужен кеш на миллион запросов в секунду» или «у нас 50 миллионов событий телеметрии в час» — ответ.
Чтобы это правило не оставалось лозунгом, разложим выбор по осям. Возьмите свои данные и пройдитесь по строкам: где набралось больше признаков одного столбца — туда и смотрите. Эта таблица — готовый чек-лист для спеки и для архитектурного ревью.
| Ось выбора | SQL (реляционная) | Документная (Mongo) | Key-value (Redis) | Колоночная (Cassandra) | Графовая (Neo4j) |
|---|---|---|---|---|---|
| Жёсткость схемы | Строгая, контролируется базой | Гибкая, на совести приложения | Нет схемы (значение по ключу) | Полугибкая, под запрос | Узлы и связи со свойствами |
| Многотабличные транзакции (ACID) | Родные и надёжные | Есть с версии 4.0, но не профиль | Практически нет | Нет (eventual) | Есть для графовых операций |
| Паттерн запросов | Любой: связи, JOIN, агрегаты | По документу/агрегату | Только по ключу | Под заранее известный запрос | Обход связей и путей |
| Масштаб записи | Один сервер (вертикально) | Шардится горизонтально | Огромный, в памяти | Очень большой, горизонтально | Ограничен связностью графа |
| Модель консистентности | Strong | Настраивается (чаще strong на реплике) | Strong на узле | Eventual (tunable) | Strong |
«Возьмём Mongo ради гибкости» — часто ложная экономия
Два факта, которые ломают этот аргумент. Первый: MongoDB с версии 4.0 (2018) умеет ACID-транзакции на нескольких документах (а с 4.2 — и на шардированном кластере), так что «в NoSQL нет транзакций» давно неправда. Второй и более важный для аналитика: PostgreSQL умеет тип JSONB — хранит документ прямо в колонке, индексирует его GIN-индексом и ищет по полям внутри. То есть большинство «документных» сценариев закрывается колонкой JSONB в той же SQL-базе — и вы сохраняете транзакции, JOIN-ы и отчётность для остальных данных рядом. Практический вывод-тейк: чаще нужен не NoSQL, а JSONB-колонка в реляционной базе. Отдельный документный движок (и вообще несколько хранилищ рядом — это называется polyglot persistence и является нормой, а не признаком переусложнения) берут, когда гибких данных реально много и они — ядро системы. Но помните цену: каждое хранилище — это ещё один источник консистентности и ещё одна операционная нагрузка.
Откуда взялся NoSQL
Откуда это взялось
Реляционные базы царили безраздельно с 1970-х. Перелом наступил, когда веб-гиганты уперлись в масштаб, которого реляционная модель на одном сервере не выдерживала. Google в 2006 описал свою систему Bigtable (колоночное хранилище под веб-масштаб), а Amazon в 2007 — Dynamo (доступность любой ценой для корзины, которая не должна «падать» в чёрную пятницу). Эти две работы запустили волну. Сам термин «NoSQL» закрепился около 2009 года — изначально как название встречи разработчиков, и расшифровывали его не «нет SQL», а «Not Only SQL» («не только SQL»), что точнее отражает суть. CAP-теорему сформулировал Эрик Брюэр около 2000 года как гипотезу, а формально доказали её в 2002-м — она и стала языком, на котором объясняют размены распределённых баз.
Частые вопросы
Чем SQL отличается от NoSQL?
SQL-базы (реляционные) хранят данные в таблицах со строгой заранее заданной схемой, связывают их ключами и дают транзакции с гарантиями ACID — это надёжность ценой строгости. NoSQL — зонтичный термин для баз с гибкой или отсутствующей схемой (документные, ключ-значение, колоночные, графовые), которые жертвуют частью строгости ради масштаба, скорости или удобной формы данных. SQL предсказуем и хорош для связанных данных и денег, NoSQL — для масштаба и гибкости под конкретную задачу.
Что такое CAP-теорема простыми словами?
Для распределённой базы из трёх свойств — согласованность (Consistency), доступность (Availability), устойчивость к разрыву сети (Partition tolerance) — одновременно гарантировать можно не все. Поскольку сеть между серверами рвётся неизбежно, устойчивость (P) обязательна, и в момент разрыва выбирают между двумя оставшимися: либо отдать только гарантированно актуальные данные ценой временной недоступности (CP, базы про деньги), либо всегда отвечать, рискуя отдать чуть устаревшее (AP, ленты и каталоги).
Когда выбирать NoSQL вместо SQL?
Когда есть конкретная причина, с которой SQL не справляется: огромный масштаб или поток записи (метрики, телеметрия, миллионы событий), данные без жёстких связей и разной формы (документы), потребность в кеше или сверхбыстром доступе по ключу (Redis), или данные, где главное — связи и пути (графы, рекомендации). По умолчанию же берут SQL: он покрывает большинство бизнес-задач. «Модно» и «гибко» — не причина; внятный ответ на «что именно тут не тянет реляционная база» — причина.
Можно ли хранить JSON в PostgreSQL и когда это лучше Mongo?
Да, для этого есть тип JSONB: документ лежит в колонке, ищется по вложенным полям, индексируется GIN-индексом. JSONB лучше Mongo, когда гибкие данные — это часть системы, а не вся система: остальное у вас в обычных таблицах, нужны транзакции, JOIN-ы и отчётность, и вы не хотите тащить второй движок и второй источник консистентности. Отдельную документную базу берут, когда документы — ядро системы, их очень много и нужен горизонтальный масштаб записи, которого одному PostgreSQL не хватает.
Что такое eventual consistency и где она допустима?
Это гарантия «данные сойдутся, но не мгновенно»: сразу после записи другой узел может вернуть ещё старое значение, а через короткое время все узлы придут к одному. Допустима там, где краткое расхождение не вредит: счётчики лайков, ленты, число просмотров, каталоги. Недопустима для денег, остатков на складе и любых данных, где устаревшее значение приведёт к неверному решению, — там нужна strong consistency. Аналитик обязан назвать требуемую модель по каждому потоку данных, а не писать абстрактное «данные должны быть согласованы».
Как это спрашивают на собесе
«Когда SQL, а когда NoSQL?» — ждут не список технологий, а правило по умолчанию: SQL покрывает связи, деньги и отчётность, NoSQL берут под конкретную причину (масштаб записи, гибкая форма, доступ по ключу, графы); «модно» — не причина. «Объясни CAP» — три свойства, P неизбежна, в момент разрыва выбор между C и A; сильный ответ добавит, что CAP — про сбой, а размен «свежесть против latency» есть и в штатном режиме (PACELC). «Что такое eventual consistency и где она допустима?» — данные сойдутся не сразу; ок для лент и счётчиков, не ок для денег и остатков. Подвох: «Можно ли хранить JSON в PostgreSQL и когда это лучше Mongo?» — здесь топят тех, кто думает, что документы = обязательно Mongo; правильный ответ называет JSONB + GIN и тезис «чаще нужен не NoSQL, а JSONB-колонка в той же SQL-базе». Подвох-добивка: «Mongo не умеет транзакций, верно?» — ответ «умеет с 4.0, multi-document» отличает мидла от джуна, который учил старые статьи.