Мурад говорит: «Давайте всё в MongoDB, она масштабируется». Лейла отвечает: «А я оставила бы всё в PostgreSQL». Кто прав? Оба наполовину. Prowid Photos хранит очень разное: аккаунты и подписки, файлы фото, счётчики лайков, сессии, поиск по подписям. Вопрос не «SQL или NoSQL», а «что нужно каждой части и чем мы готовы пожертвовать». В этом уроке разберём семейства хранилищ, ACID и BASE, теорему CAP (и что такое «разделение сети»), модели согласованности и выбор хранилища для каждой части системы.
«SQL или NoSQL» — неточный вопрос
NoSQL расшифровывают как «not only SQL». Это не один вид баз, а россыпь семейств, появившихся в 2000-х, когда понадобилось расти на много серверов, хранить гибкие данные и быстро отвечать на узкие запросы. Границы размыты: PostgreSQL хранит JSON (jsonb), а MongoDB умеет транзакции. Основные семейства:
| Семейство | Примеры | Сильная сторона |
|---|---|---|
| Реляционные | PostgreSQL, MySQL | связи, JOIN, ограничения, ACID |
| Документные | MongoDB, Firestore | вложенные JSON-документы, гибкая схема |
| Ключ–значение | Redis, Memcached, DynamoDB | get/set по ключу за доли миллисекунды, TTL |
| Wide-column | Cassandra, ScyllaDB | огромный поток записей, рост добавлением узлов |
| Графовые | Neo4j, Neptune | обход связей на много шагов |
| Поисковые | OpenSearch, Meilisearch | полнотекстовый поиск, релевантность |
💡 Не путайте wide-column (Cassandra) с аналитическими колоночными базами (ClickHouse, BigQuery): те хранят данные по столбцам и быстро считают агрегаты по миллиардам строк. А файлы фото не лежат ни в одной из них — для них объектное хранилище S3.
Реляционные базы и ACID
Таблицы, строгая схема, SQL и главный козырь — ACID-транзакции: Atomicity (все изменения применяются или ни одно), Consistency (ограничения не нарушены), Isolation (параллельные транзакции не портят друг другу данные), Durability (подтверждённое не пропадёт при сбое). Классика — перевод 100 AZN от Лейлы Мураду:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- Leyla
UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- Murad
COMMIT; -- both changes happen, or neither doesРеляционная база идеальна, когда данные связаны, важна целостность и нужны запросы «как угодно». Она растёт вертикально и репликами; шардирование, как мы видели, сложнее.
Остальные семейства на примерах
Документная модель хранит то, что читается вместе, вместе, без JOIN. Схема гибкая, но данные дублируются, а связи между документами — слабое место. С MongoDB вы работали в уроке «MongoDB: документная модель и запуск базы»:
const photo = {
_id: 'p42',
owner: { id: 7, name: 'Leyla' },
caption: 'Baku at night',
tags: ['baku', 'night', 'city'],
exif: { camera: 'X100V', iso: 800 },
comments: [
{ by: 'Murad', text: 'Great shot!' },
{ by: 'Aysel', text: 'Where is this?' },
],
};