Экспресс-курс · No. 06
Языки и фреймворки приходят и уходят. Данные, которые ты хранишь, и форма, в которой ты их хранишь, могут пережить их все — поэтому выбрать базу значит выбрать, как твоя система помнит и насколько тяжело ей передумать.
20 понятий · схема у каждого · шпаргалка в конце
База данных — это долговременная память твоей системы. Код переписывают; данные и форма, которую ты для них выбрал, обычно переживают всё вокруг.
Данные переживают код
Дом за десятилетия перекрашивают, переставляют мебель, даже перекрывают крышу — но фундамент, залитый в первый день, остаётся, потому что заменить его значит поднять весь дом.
Языки меняются, фреймворки подменяют, интерфейс перерисовывают десять раз. Данные и их структура обычно остаются, потому что менять их на живой системе, полной реальных записей, медленно и рискованно. Поэтому база — первое, о чём надо подумать всерьёз, и последнее, что стоит делать впопыхах.
База отвечает на два вопроса
Выбор, где хранить вещи, задаёт два вопроса: какой они формы — книги на полках или странные инструменты на крючках? — и насколько надёжно их надо беречь — сейф или удобный ящик?
Любое хранилище определяется двумя вещами. Первая — модель данных (data model): как оно придаёт данным форму — жёсткие таблицы, гибкие документы, граф связей. Вторая — гарантии (guarantees): строгая корректность или скорость и доступность с более слабыми обещаниями. Почти любой выбор базы — это разный ответ на эти два вопроса, и остальной курс — это меню.
Access pattern — выбирай по тому, как читаешь и пишешь
Картотечный шкаф, каталог карточек и конвейер — всё это «хранилище», но выбираешь ты по тому, как будешь доставать вещи, а не по тому, что выглядит новее.
Лучшей базы не бывает. Хранилище, идеальное под быстрые поиски по ключу, плохо для глубоких запросов по связям; построенное под огромные записи плохо для строгих банковских транзакций. Правильный вопрос — твой паттерн доступа (access pattern): что ты читаешь, что пишешь, как часто и как это должно вести себя, когда что-то идёт не так.
Карта: 20 понятий в шести группах
Карта метро: сначала видишь линии целиком, потом едешь по станциям.
Понятия курса делятся на шесть групп: реляционная основа, семейство NoSQL, специализированные хранилища, гарантии, приёмы масштабирования и то, как всё это сочетать.
У каждого понятия дальше одно и то же: английское название (это термин, по которому его ищут в документации), образ из жизни, схема и карточка с полями: проблема, идея, пример, цена, когда брать и связи. В конце — шпаргалка на одной странице.
Код легко поменять. Данные — нет. Выбирай хранилище как решение, с которым проживёшь годы, — потому что так и будет.
Для большинства систем дефолт — реляционная база, и этот дефолт она заслуживает. Начинай отсюда и уходи только с причиной.
Relational Database — таблицы, строки и связи
Правильно сделанная таблица: каждый лист — один вид сущности (клиенты, заказы), каждая строка — одна запись, и заказы ссылаются назад на клиента, которому принадлежат.
Это понятие реляционная база данных (relational database). Она хранит данные в таблицах (tables) с фиксированной схемой (schema) и связывает таблицы по ссылке — строка заказа держит id своего клиента. Такая ссылка называется внешний ключ (foreign key). Схема — это обещание о форме: у каждого заказа есть нужные колонки, проверенные на входе. Структура заранее в обмен на здравомыслие потом.
- Проблема
Данные со структурой и связями, к которым нужно задавать разные вопросы.
- Идея
Таблицы с фиксированной схемой; связи между таблицами через внешние ключи.
- Пример
Postgres, MySQL: таблицы
customersиorders, у заказа естьcustomer_id.- Цена
- Схему надо продумать заранее; менять её на живых данных — работа.
- Когда брать
Почти всегда как стартовая точка. Уходить — только с причиной.
- Связи
- Говорит на SQL, даёт Transactions и ACID.
SQL — проси что хочешь, а не как достать
Ты говоришь библиотекарю «все романы французских авторов, изданные после 1950-го, по году» — и он сам соображает, как их найти. Ты описываешь результат, а не поиск.
SQL (Structured Query Language) — это декларативный язык запросов (declarative query language): ты заявляешь нужный ответ, а база сама строит план, как его достать, включая соединение таблиц (JOIN). Этот план строит планировщик запросов (query planner). SELECT ... JOIN ... WHERE ... может ответить на вопросы, которых ты не предвидел при проектировании, — одна из тихих суперсил реляционной модели.
- Проблема
- Нужно задавать данным вопросы, не программируя каждый поиск вручную.
- Идея
- Описываешь результат; база сама выбирает план (индексы, соединения, сортировку).
- Пример
SELECT title FROM books JOIN authors ... WHERE country = 'FR' AND year > 1950 ORDER BY year.- Цена
- Сложные запросы надо уметь читать и проверять, как именно база их выполняет.
- Когда брать
- Везде, где есть реляционная база, — это её родной язык.
- Связи
- Язык Relational Database; быстрым его делают индексы (Index).
Transactions — всё или ничего
Денежный перевод — это две записи: минус здесь, плюс там, — но одно намерение. Либо обе случились, либо ни одна; наполовину сделанный перевод — катастрофа.
Это понятие транзакция (transaction): группа изменений, которая либо целиком фиксируется (commit), либо целиком откатывается (rollback), изолированно от других, и переживает падение, как только подтверждена. Набор этих обещаний называют ACID (подробно — в главе 5). Поэтому банки, заказы и склад живут в SQL — когда корректность важнее голой скорости, тебе нужно именно это обещание.
- Проблема
Одно действие — это несколько записей; сбой посередине оставит мусор.
- Идея
- Обернуть записи в
BEGIN … COMMIT: либо все сохранились, либо ни одна. - Пример
- Перевод:
A − 100иB + 100в одной транзакции. - Цена
- Немного скорости и более тяжёлое масштабирование по машинам.
- Когда брать
- Деньги, заказы, склад — всё, где неверное число недопустимо.
- Связи
- Свойства транзакции и есть ACID.
Почему это правильный дефолт
Хороший универсальный инструмент: не самый быстрый в каком-то одном деле, но тот, за которым тянешься, пока задача специально не потребует иного.
Структурированные данные, реальные связи, произвольные запросы, сильные гарантии — реляционная база делает всё это хорошо, а современный Postgres ещё и тянет JSON, полнотекстовый поиск и даже векторы. Начинай каждый проект здесь; тянись за чем-то другим, только когда конкретная боль — масштаб, форма или паттерн доступа — выталкивает тебя.
Начинай с Postgres. Вопрос не «зачем SQL» — а есть ли у тебя реальная причина его не брать.
Иногда жёсткая таблица — неправильная форма. «NoSQL» — это на самом деле семейство хранилищ, и каждое гнёт правила в свою сторону ради своей задачи.
Document Store — по JSON-документу на сущность
Папка заполненных анкет, где у каждой могут быть слегка разные поля — нет центрального шаблона, заставляющего все совпадать.
Это документное хранилище (document store). Оно хранит записи как гибкие JSON-подобные документы, вложенные и почти бессхемные (schema-less), так что две записи в одной коллекции (collection) могут различаться. Хорошо, когда формы разнятся или быстро меняются, и целая сущность — товар, профиль — живёт как один документ, который ты достаёшь за одно чтение.
- Проблема
- Формы записей разные или быстро меняются; таблица мешает.
- Идея
- Каждая сущность — один вложенный JSON-документ, без общей жёсткой схемы.
- Пример
- MongoDB: каталог товаров, профили пользователей.
- Цена
- Меньше гарантий и сложнее запросы между документами, чем в SQL.
- Когда брать
- Сущность читается целиком, а поля у разных записей разные.
- Связи
Postgres тоже умеет документы (JSONB); часто живёт по правилам BASE.
Key-Value Store — гигантская хеш-таблица
Гардероб — отдаёшь номерок, получаешь ровно своё пальто. Никаких поисков, никаких вопросов, мгновенно.
Это хранилище ключ-значение (key-value store) — простейшая форма: ключ на входе, значение на выходе, ослепительно быстро. Идеально для кэша, сессий, счётчиков ограничения запросов (rate limit) и всего, что ты достаёшь по известному id.
- Проблема
- Нужно очень быстро доставать данные по известному id.
- Идея
- Ключ → значение, как гигантская хеш-таблица.
- Пример
- Redis, DynamoDB:
session:42, кэш страницы, счётчик rate limit. - Цена
- Искать можно только по ключу — богатых запросов по самим значениям нет.
- Когда брать
- Кэш, сессии, счётчики — всё, где id известен заранее.
- Связи
Типичный «быстрый помощник» рядом с основной базой в Polyglot persistence.
Wide-Column Store — под огромные потоки записей
Огромный склад с бесконечными одинаковыми проходами, устроенный так, чтобы тысяча погрузчиков расставляла товар одновременно, не сталкиваясь.
Это хранилище широких колонок (wide-column store). Оно размазывает данные по множеству машин по ключу партиции (partition key) ради огромной пропускной способности записи и масштаба, меняя богатые запросы и строгую согласованность на способность принять брандспойт данных. Мощно — и больше работы по эксплуатации.
- Проблема
- Записей так много, что одна SQL-машина прогнётся.
- Идея
- Разложить данные по многим узлам по ключу партиции; писать параллельно.
- Пример
- Cassandra: логи событий, телеметрия, ленты на большом масштабе.
- Цена
- Нет богатых запросов и строгой согласованности; сложнее эксплуатировать.
- Когда брать
- Брандспойт записей, а запросы заранее известны и простые.
- Связи
- По сути встроенный Sharding; обычно живёт по BASE.
Graph Database — когда суть в связях
Доска детектива — фото, соединённые нитями. Ценность не в отдельном фото, а в паутине того, кто с кем связан.
Это графовая база данных (graph database). Она моделирует данные как узлы (nodes) и рёбра (edges) между ними, делая запросы по связям — «друзья друзей, которым это нравится», «путь между этими двумя аккаунтами» — естественными и быстрыми там, где SQL понадобились бы болезненные многосторонние соединения. Тянись за этим, когда связи важнее самих записей.
- Проблема
- Главные вопросы — про связи, и в SQL это многоэтажные JOIN.
- Идея
- Узлы и рёбра — первоклассные данные; запрос идёт по рёбрам.
- Пример
- Neo4j: социальный граф, рекомендации, выявление мошенничества.
- Цена
- Узкая ниша; для обычных записей и отчётов неудобна.
- Когда брать
- Связи важнее самих записей.
- Связи
- Альтернатива Relational Database, когда JOIN становится болью.
NoSQL — это не «новее SQL». Каждое хранилище сбрасывает какую-то гарантию ради чего-то конкретного — знай, чем именно ты жертвуешь.
За универсальными хранилищами стоят базы, сделанные под одну задачу, где специализированный движок обходит универсальный на голову.
Time-Series Database — данные со штампом времени
Лента кардиомонитора — бесконечная полоса показаний, каждое привязано к моменту, и ты почти всегда спрашиваешь «что было между этими двумя временами?»
Это база временных рядов (time-series database). Она заточена под данные, которые приходят по порядку времени и запрашиваются по времени — метрики, показания датчиков, цены. Принимает огромные потоки и быстро отвечает «среднее за минуту за прошлую неделю», со встроенным удалением старых данных (retention).
- Проблема
- Огромный поток показаний, и все вопросы — «что было за этот период».
- Идея
- Хранить и индексировать по времени; быстро агрегировать окна.
- Пример
- InfluxDB, TimescaleDB: метрики серверов, датчики, цены.
- Цена
- Ещё одно хранилище; для обычных бизнес-данных не подходит.
- Когда брать
- У всего есть метка времени, и время — главная ось.
- Связи
- TimescaleDB — расширение Postgres, см. Postgres first.
Search Engine — полный текст и релевантность
Строка поиска, которая прощает опечатки, ставит лучшие совпадения первыми и находит «running», когда ты набрал «run», — как библиотекарь, понимающий, что ты имел в виду.
Это поисковый движок (search engine). Он строит обратный индекс (inverted index) — «слово → документы» — ради быстрого полнотекстового поиска (full-text search) с ранжированием, нечётким совпадением и фильтрами — того, что LIKE '%word%' в SQL делает медленно и плохо. Обычно работает рядом с основной базой, держится в синхроне и питает строку поиска и разбор логов.
- Проблема
LIKE '%word%'медленный, не прощает опечаток и не ранжирует.- Идея
- Обратный индекс слов + оценка релевантности.
- Пример
- Elasticsearch, OpenSearch: строка поиска на сайте, разбор логов.
- Цена
- Надо держать в синхроне с основной базой.
- Когда брать
- Пользователи ищут по тексту и ждут «умного» поиска.
- Связи
Не источник правды — быстрая линза на него; часть Polyglot persistence.
Vector Database — поиск по смыслу
Вместо совпадения точных слов ты спрашиваешь «найди то, что похоже на это» — и получаешь соседей по сходству, а не по ключевому слову.
Это векторная база данных (vector database). Она хранит embeddings — числовые отпечатки смысла — и находит ближайшие (nearest neighbours), так что ты ищешь по сходству, а не по точному тексту. Это движок под семантическим поиском (semantic search) и RAG, где AI-приложение достаёт самые релевантные куски, чтобы из них ответить.
- Проблема
- Нужно найти похожее по смыслу, а слова могут не совпадать.
- Идея
- Хранить embeddings и искать ближайших соседей.
- Пример
pgvector, Pinecone: по запросу «refund policy» найти «returns» и «money back».
- Цена
- Нужна модель embeddings и синхронизация с исходными данными.
- Когда брать
Семантический поиск и RAG — новое обязательное хранилище эпохи AI.
- Связи
- pgvector — расширение Postgres; копия данных, как Search Engine.
Object Storage — куда кладут большие файлы
Бокс на складе самообслуживания — не для карточек, а для мебели: громоздкие вещи, которые держишь по ярлыку и вывозишь целиком.
Это объектное хранилище (object storage). Оно не база данных, но именно туда кладут большие блобы (blobs) — картинки, видео, бэкапы, документы — адресуемые ключом (key) внутри бакета (bucket) и отдаваемые дёшево на масштабе. Паттерн почти универсален: файл — в объектном хранилище, а строку, указывающую на него, — в базе. Записи в БД, нагрузка в бакете.
- Проблема
- Большие файлы в базе раздувают её и дорого отдаются.
- Идея
- Файл — в бакете по ключу; в базе — только строка с этим ключом.
- Пример
- S3 и его собратья: фото, видео, бэкапы, документы.
- Цена
Не база: запросов по содержимому нет, только «положить/достать по ключу».
- Когда брать
- Любые большие файлы.
- Связи
- По форме похоже на Key-Value Store, только для громоздких вещей.
Не выгибай основную базу в поисковый движок или файловый сервер. Специализированную задачу клади в хранилище, построенное под неё.
Самый глубокий выбор базы — не её форма, а то, что она обещает, когда что-то идёт не так. Небольшой алфавитный суп называет этот размен.
ACID — пессимистично, корректно, осторожно
Кассир в банке, который перепроверяет каждую запись и не двинется дальше, пока книги не сойдутся, — медленнее, зато никогда не ошибается.
ACID — это строгое обещание реляционных баз о транзакциях: каждая транзакция оставляет данные корректными и полными или не происходит вовсе. Четыре буквы: Atomicity (всё или ничего), Consistency (правила данных всегда соблюдены), Isolation (параллельные транзакции не мешают друг другу), Durability (подтверждённое переживает падение). Для денег, заказов и всего, где неверное число недопустимо, это тот размен, что тебе нужен.
- Что обещает
- Каждая транзакция целиком корректна или не случилась вовсе.
- Пример
- Банковский перевод, оформление заказа, списание со склада.
- Цена
- Некоторая скорость и более тяжёлое масштабирование по машинам.
- Когда брать
- Неверное число недопустимо.
- Связи
- Свойства Transaction; противоположная позиция — BASE.
BASE — оптимистично, доступно, в итоге верно
Оживлённый магазин, где всем дают покупать, даже пока обновляют ценники, — числа догонят через миг, и это нормально.
Многие NoSQL-системы занимают противоположную позицию: BASE (Basically Available, Soft state, Eventually consistent). Они остаются быстрыми и доступными и принимают, что копии данных могут ненадолго расходиться, прежде чем сойтись. Это называется согласованность в конечном счёте (eventual consistency).
- Что обещает
- Система всегда отвечает; копии сходятся «в итоге».
- Пример
- Счётчик лайков, лента, счётчик просмотров.
- Цена
- Можно ненадолго увидеть устаревшее значение.
- Когда брать
Доступность важнее мгновенной точности, и секунда устаревания ничего не стоит.
- Связи
- Противоположность ACID; выбор «A» в CAP.
CAP Theorem — при обрыве сети выбирай
Команда, разрезанная упавшей телефонной линией: каждая половина может работать сама (но они разойдутся) или сложить инструменты до восстановления связи (но ты встаёшь). И то, и другое сразу — нельзя.
Теорема CAP (CAP theorem) говорит: когда сетевой раздел (network partition) разрезает машины твоей базы, ты должен выбрать Consistency (отказывать в записи, оставаться корректным) или Availability (продолжать обслуживать, рискуя расхождением) — оба сразу во время раздела невозможны. Любая распределённая база делает этот выбор. Знать, что выбирает твоё хранилище, — значит знать, как оно ведёт себя в худший день.
- Что говорит
При разрыве сети нельзя одновременно быть и корректным, и доступным.
- Пример
Два узла потеряли связь: отказать в записи (CP) или принять её на обоих и потом мирить (AP).
- Цена
- CP — простой; AP — устаревшие или конфликтующие данные.
- Когда думать
- Как только данные живут больше чем на одной машине.
- Связи
- Встаёт из-за Replication и Sharding; AP-сторона — это BASE.
ACID для денег, BASE для лайков. Нужная гарантия задаётся ценой того, чтобы ненадолго ошибиться.
Горстка приёмов превращает базу из одной хрупкой коробки в нечто быстрое и живучее. Со всеми ты столкнёшься.
Index — предметный указатель для данных
Чтобы найти слово в книге на 900 страниц, ты не читаешь каждую страницу — ты открываешь указатель в конце и прыгаешь прямо к нему.
Индекс (index) — это побочная структура, превращающая полный перебор таблицы (full table scan) в прямой поиск, самый большой рычаг скорости чтения. Подвох: каждый индекс стоит места и замедляет записи (каждая вставка должна обновить и его).
- Проблема
- Запрос читает всю таблицу, и с ростом данных становится медленным.
- Идея
- Отсортированная побочная структура по колонке → прямой поиск строки.
- Пример
- Индекс по
email: найти пользователя — без перебора всей таблицы. - Цена
- Место на диске и медленнее каждая запись.
- Когда брать
На колонки, по которым реально фильтруешь и сортируешь, — не на все подряд.
- Связи
- Ускоряет SQL; поисковый движок — это особый индекс по тексту.
Replication — держи копии, переживай отказ
Документ, хранимый в трёх сейфах в трёх зданиях — если одно сгорит, другие всё равно держат его, и трое могут читать одновременно.
Репликация (replication) держит копии данных на нескольких машинах. Все записи идут в лидера (leader), а реплики (followers, replicas) получают копию и обслуживают чтения. Если лидер умирает, его место занимает реплика (failover). Подвох — лаг репликации (replication lag): реплика может отставать на миг, так что только что записанное значение может ещё не показаться на ней.
- Проблема
- Одна машина — одна точка отказа и предел по чтениям.
- Идея
- Те же данные на нескольких машинах: лидер пишет, реплики читают.
- Пример
Postgres с двумя репликами для чтения; при падении лидера реплика становится лидером.
- Цена
- Лаг: свежая запись может ещё не дойти до реплики.
- Когда брать
- Нужна надёжность или чтений больше, чем тянет одна машина.
- Связи
Копирует одни и те же данные; Sharding делит разные. Обе ведут к CAP.
Sharding — дели, когда одной машины мало
Один переполненный картотечный шкаф становится A–M в одном шкафу и N–Z в другом. Больше места — но теперь надо знать, в каком шкафу живёт имя.
Когда данные или нагрузка на запись перерастают одну машину, шардинг (sharding) делит данные по многим — пользователи A–M здесь, N–Z там. Каждая часть называется шард (shard), а поле, по которому делим, — ключ шардирования (shard key). Это открывает почти безграничный масштаб, но ключ шардирования — тяжёлый, почти необратимый выбор: ошибёшься — получишь горячие точки (hotspots) или запросы, которым приходится бить по всем шардам.
- Проблема
- Данные или поток записей не помещаются в одну машину.
- Идея
- Разделить данные по ключу между многими машинами.
- Пример
- Пользователи A–M на шарде 1, N–Z на шарде 2.
- Цена
Ключ почти не поменять; плохой ключ → горячие точки или запросы по всем шардам.
- Когда брать
- Последним: после индексов и реплик.
- Связи
Встроен в Wide-Column Store; вместе с Replication ведёт к CAP.
Normalization / Denormalization — один факт в одном месте или копии ради скорости
Один общий список адресов, на который все ссылаются (без противоречий), против пришитой копии адреса к каждому заказу (читать быстрее, но теперь есть копии, которые надо держать честными).
Нормализация (normalization) держит каждый факт ровно в одном месте — чисто, без противоречий, реляционный дефолт. Денормализация (denormalization) намеренно дублирует данные, чтобы чтения были быстрее и требовали меньше соединений. Оба подхода годятся; правило — делать это осознанно и всегда знать, какая копия источник правды (source of truth), а какая просто быстрый дубль. (Тот же урок, что с кэшем.)
- Проблема
Один и тот же факт в нескольких местах расходится; а соединения замедляют чтения.
- Идея
- Нормализуй по умолчанию; денормализуй осознанно там, где чтения важнее.
- Пример
- Адрес в одной таблице
addressesпротив копии адреса в каждом заказе. - Цена
Нормализация — больше JOIN; денормализация — копии, которые надо синхронизировать.
- Когда брать
- Денормализацию — когда измеренно медленные чтения требуют этого.
- Связи
Та же идея «источник правды + быстрые копии», что в Polyglot persistence.
Сначала индекс, потом сервер; сначала реплика, потом шард. Самое дешёвое масштабирование — то, которое не приходится эксплуатировать.
Ты не выбираешь одну базу и не запихиваешь в неё всё. Реальные системы используют несколько, каждую под задачу, в которой она лучше всего.
Polyglot Persistence — несколько хранилищ осознанно
На кухне есть холодильник, морозилка и кладовка — а не одна коробка, заставленная делать всё три. Каждая держит то, что ей подходит.
Это паттерн Polyglot persistence — «многоязычное хранение». Зрелые системы обычно используют несколько хранилищ: Postgres как источник правды, Redis для кэша и сессий, поисковый индекс для строки поиска, может быть, векторное хранилище для AI-фич и объектное хранилище для файлов. Каждое делает то, в чём хорошо. Дисциплина в том, чтобы ясно держать, какое из них хранит правду, а остальные — быстрые копии, держащиеся в синхроне.
- Проблема
- Одна база не может быть лучшей во всём сразу.
- Идея
- Каждой задаче — своё хранилище; один явный источник правды.
- Пример
- Postgres + Redis + поисковый индекс + векторное хранилище + S3.
- Цена
- Каждое хранилище надо эксплуатировать, бэкапить и держать согласованным.
- Когда брать
Когда реальная боль требует ещё одного хранилища, а не «на всякий случай».
- Связи
- Начинается с Postgres first; объединяет почти все хранилища курса.
Postgres First — начинай с Postgres, вырастай осознанно
Швейцарский нож тянет поразительно много, прежде чем тебе вообще понадобится полный набор инструментов.
Это практика Postgres first. Современный Postgres поразительно способен — реляционное ядро, JSON-документы, полнотекстовый поиск, векторы, даже рабочая очередь задач. Большинство продуктов должны начинать просто с Postgres и добавлять специализированное хранилище, только когда реальная, измеренная боль этого требует. Каждая лишняя база — это ещё одно, что надо эксплуатировать, бэкапить и держать согласованным. Самое дешёвое хранилище — то, которое ты не добавил.
- Проблема
- Команда добавляет базы раньше, чем появляется боль.
- Идея
- Один Postgres, пока измеренная проблема не потребует большего.
- Пример
JSONB вместо отдельной документной базы, pgvector вместо отдельной векторной.
- Цена
- На очень большом масштабе специализированный движок всё же обгонит.
- Когда брать
- В начале почти любого продукта.
- Связи
- Первый шаг к Polyglot persistence — когда «пока что» закончилось.
Как всё связано
Карта района после прогулки: теперь видно, какие улицы куда ведут.
Понятия курса не живут поодиночке. Реляционная база — источник правды с гарантиями ACID; индекс ускоряет её чтения; поисковый движок и векторная база — копии, которые от неё питаются; в объектном хранилище лежат файлы, на которые указывают её строки. Когда одной машины мало, приходят репликация и шардинг — и вместе с ними выбор CAP. NoSQL-семейство часто выбирает BASE — противоположность ACID.
- Какой формы данные — таблицы, документы, ключ-значение, граф?
- Как я буду их запрашивать — по id, по связям, по тексту, по сходству, по времени?
- Какие гарантии мне нужны — строгий ACID или сойдёт eventually consistent?
- Каков баланс чтений/записей и примерный масштаб?
- Не смог бы Postgres уже это сделать, прежде чем я добавлю ещё хранилище?
- Какое хранилище держит источник правды, а какие — просто копии?
- Ты гоняешь
LIKE '%...%'для поиска вместо поискового движка. - Хранилище ключ-значение там, где постоянно нужно запрашивать по значениям.
- Пять баз для продукта, который поддерживают два человека.
- Ты взял MongoDB, чтобы избежать схем, а потом всё равно руками собрал валидацию.
- Нет ясного источника правды — два хранилища оба претендуют на авторитет.
- Запрос, который ты гоняешь чаще всего, — тот, в котором хранилище быстрее всего.
- Гарантия соответствует ставкам — строгая для денег, расслабленная для лайков.
- Ты можешь назвать источник правды для каждого важного факта.
- Ты добавил каждое хранилище, чтобы решить реальную, прочувствованную боль, а не гипотетическую.
- Ты мог бы объяснить модель данных новому инженеру за несколько минут.
Шпаргалка: все 20 понятий
Реляционная основа
- Relational Databaseреляционная БД
Таблицы с фиксированной схемой, связи через внешние ключи. Дефолт.
- SQLязык запросов
Описываешь, что нужно; база сама решает, как достать.
- Transactionтранзакция
Несколько записей как одно целое: COMMIT всех или ROLLBACK всех.
Семейство NoSQL
- Document Storeдокументная БД
Гибкие JSON-документы; сущность читается целиком.
- Key-Value Storeключ-значение
Ключ → значение, мгновенно. Кэш, сессии, счётчики.
- Wide-Column Storeширокие колонки
Данные по многим машинам ради брандспойта записей.
- Graph Databaseграфовая БД
Узлы и рёбра; запросы по связям без мучительных JOIN.
Специализированные хранилища
- Time-Series Databaseвременные ряды
Показания по времени; запросы окнами, старое удаляется.
- Search Engineпоисковый движок
Полнотекстовый поиск с ранжированием и опечатками. Копия, не правда.
- Vector Databaseвекторная БД
Embeddings и поиск ближайших по смыслу. Основа RAG.
- Object StorageS3
Большие файлы по ключу в бакете; в базе — только ссылка.
Гарантии
- ACIDстрогое обещание
Транзакция целиком корректна или не случилась. Для денег.
- BASEeventual consistency
Всегда доступно, копии сходятся в итоге. Для лайков.
- CAP Theoremтеорема CAP
При разрыве сети — либо корректность, либо доступность.
Масштаб
- Indexиндекс
Указатель для быстрого чтения; цена — место и медленные записи.
- Replicationрепликация
Те же данные на многих машинах: надёжность и чтения. Есть лаг.
- Shardingшардинг
Разные данные на разных машинах по ключу. Ключ почти не поменять.
- Normalization / Denormalizationнормализация
Один факт в одном месте — или осознанные копии ради скорости.
Как выбирать
- Polyglot Persistenceнесколько хранилищ
Каждой задаче своё хранилище, один источник правды.
- Postgres Firstначинай с Postgres
Один Postgres, пока реальная боль не потребует большего.
Лучшее решение по базе обычно — «Postgres, пока что» — плюс мудрость понять ровно тот момент, когда «пока что» закончилось.