Базы данных и хранение на собеседовании системного аналитика
Зачем SA спрашивают про БД
SA не пишет код в БД, но проектирует данные: какие таблицы, какие связи, где нужны индексы, как партиционировать. Без этого нельзя оценить нагрузку, сформулировать requirements для разработчиков, обсудить trade-off-ы.
На собесе системного аналитика БД — обязательный блок, 45-60 минут. Уровень: junior — знает SQL, normalization; middle — индексы, типы JOIN; senior — шардирование, репликация, выбор СУБД для use case.
SQL vs NoSQL
SQL (RDBMS): PostgreSQL, MySQL, Oracle.
- Структурированные данные с фиксированной схемой
- Сильные гарантии (ACID)
- Сложные запросы (JOIN, агрегаты)
- Вертикальное масштабирование, реплики для чтения
NoSQL: разные виды.
- Document DB (MongoDB, Couchbase). JSON-документы. Гибкая схема.
- Key-value (Redis, DynamoDB). Простой доступ по ключу.
- Wide-column (Cassandra, HBase). Большие таблицы с гибкими колонками.
- Graph (Neo4j). Связи между сущностями.
- Time-series (InfluxDB, TimescaleDB). Временные ряды.
- Search (Elasticsearch, OpenSearch). Полнотекстовый поиск.
Когда что выбирать:
| Use case | Подходит |
|---|---|
| Транзакционная система (заказы, платежи) | RDBMS (Postgres) |
| Большие объёмы read-heavy, простые ключи | Key-value (Redis, Dynamo) |
| Сложные документы переменной структуры | Document (MongoDB) |
| Аналитика на масштабе | OLAP (ClickHouse, BigQuery) |
| Полнотекстовый поиск | Search (Elasticsearch) |
| Социальный граф | Graph (Neo4j) |
| Метрики времени | Time-series (Timescale) |
Нормализация
Уровни нормальных форм:
1NF: атомарность значений (нет списков в одной колонке).
2NF: 1NF + нет частичной зависимости от композитного ключа.
3NF: 2NF + нет транзитивных зависимостей (атрибут зависит только от PK, не от другого атрибута).
BCNF: 3NF + все детерминанты — кандидатные ключи.
На практике в OLTP — 3NF или близко к ней. В OLAP — денормализация (star schema, агрегаты).
Когда денормализовать:
- Высокая нагрузка чтения, JOIN-ы стоят дорого
- Аналитика на масштабе (star/snowflake schema)
- Read-heavy + low write rate
Индексы
Индекс — структура для ускорения поиска по колонке. Trade-off: ускоряет SELECT, замедляет INSERT/UPDATE/DELETE.
B-tree — default. Хорошо для:
- Равенство
WHERE col = X - Диапазон
WHERE col BETWEEN A AND B - LIKE с префиксом
WHERE col LIKE 'abc%' - ORDER BY
Hash — только равенство. В Postgres с PG10+ можно использовать в production.
GIN — для arrays, JSONB, full-text search.
BRIN — для огромных таблиц по time/sequential колонкам. Очень компактный.
Composite index — несколько колонок. Order matters: (a, b) работает для WHERE a = ... AND b = ..., но не для WHERE b = ... only.
Partial index — WHERE condition в определении индекса. Например, CREATE INDEX ON orders(user_id) WHERE status = 'active'.
Covering index — INCLUDE дополнительные колонки. Запрос становится index-only scan.
Транзакции и блокировки
Optimistic locking — без блокировки. Версионирование (version column). При update проверяем, не изменилась ли версия. Если изменилась — retry.
Pessimistic locking — SELECT ... FOR UPDATE. Блокирует строки до конца транзакции.
Deadlock — две транзакции ждут друг друга. Решение: detection в СУБД (одна транзакция rollback с ошибкой). Профилактика: всегда захватывать locks в одном порядке.
Репликация
Master-slave (legacy term) или primary-replica.
Synchronous replication: primary не возвращает success, пока replica не записала. Strong consistency, медленный, hopin.
Asynchronous replication: primary возвращает success сразу. Replica догоняет. Eventual consistency, lag (10ms-секунды).
Read replicas: реплики только для чтения. Снижают нагрузку на primary.
Multi-master: запись возможна на любой replica. Конфликты (CRDT, vector clocks).
Шардирование
Когда одна БД не справляется — разделяем данные по нескольким серверам (shards).
Hash sharding: shard = hash(key) % N. Равномерное распределение, но трудно добавлять shards (rehashing).
Range sharding: shard = range(key). Например, по дате. Легко добавлять, но риск hot shard.
Geographic sharding: по региону. Хорошо для compliance и latency.
Consistent hashing: добавление shard не требует полного rehashing. Используется в DynamoDB, Cassandra.
Проблемы шардирования:
- Cross-shard joins — медленные или невозможны. Решение: денормализация, replication справочников.
- Cross-shard transactions — нужны distributed transactions (2PC, Saga).
- Rebalancing при добавлении shard — миграция данных.
Типичные вопросы
«PostgreSQL vs MongoDB — когда что?»
PostgreSQL — для структурированных данных с relationships, транзакций, сложных запросов. MongoDB — для гибкой схемы, document-based данных, простых запросов.
В большинстве OLTP — Postgres. MongoDB оправдан для специфических use case (e-commerce catalog с переменной структурой, CMS).
«Когда нужен индекс, а когда лишний?»
Нужен: на колонках в WHERE, JOIN, ORDER BY. Особенно если selectivity высокая (мало повторов).
Лишний: на маленьких таблицах, на колонках с очень низкой cardinality (boolean), на write-heavy таблицах. Каждый индекс замедляет INSERT.
«Что такое OLTP vs OLAP?»
OLTP (Online Transaction Processing) — маленькие транзакции, частые INSERT/UPDATE, узкие запросы. Postgres для биллинга.
OLAP (Online Analytical Processing) — большие сканы, агрегаты, чтение преобладает. ClickHouse / Snowflake.
«Спроектируй БД для маркетплейса»
OLTP в Postgres: users, products, orders, order_items, payments, reviews. Связи через FK. Нормализация 3NF.
OLAP в ClickHouse: денормализованные facts (fact_orders, fact_views), dimensions.
«Как уменьшить нагрузку на primary?»
(1) Read replicas — чтение с replicas, write на primary. (2) Cache (Redis) перед DB. (3) Шардирование если данных слишком много. (4) Архивирование старых данных.
Частые ошибки
- «MongoDB быстрее». Зависит от use case. MongoDB сложно делать JOIN-ы. Для structured data Postgres быстрее.
- Индексы на всё. Каждый индекс — overhead на запись + storage. Только нужные.
- Игнорировать репликацию. В production без replicas — single point of failure.
- Шардирование когда не надо. Если справляется одна БД — не усложняй.
- JSONB вместо нормализации. JSONB удобен, но JOIN-ы и индексы по полям JSONB сложнее.
FAQ
SQL или NoSQL — что популярнее на собесах?
SQL. Большинство production систем — Postgres / MySQL. NoSQL — для специфических задач.
Нужно ли уметь оптимизировать запросы?
На уровне SA — общее понимание (где индекс нужен, что такое EXPLAIN). Глубокая оптимизация — для DE/DBA.
Что такое CQRS?
Command-Query Responsibility Segregation. Разделение модели на чтение и запись. Запись в нормализованной БД, чтение — из денормализованных read-моделей (можно eventual consistency).
Спрашивают ли про NoSQL детально?
Зависит от компании. Если работа с MongoDB / Cassandra — да. В банках обычно SQL.
Сколько готовиться?
Junior — 2-3 месяца с practice. Middle/Senior — 2-4 недели.