# Базы данных и хранилища

← [Раздел](README.md) · [Главная](../README.md)

## Цель

Различать типы **хранилищ данных** в облаке: реляционные БД, документные, кэш, object storage — и понимать, **когда** какое использовать в архитектуре.

## Предварительно

- [API и шлюзы](api-i-shlyuzy.md)

## Время

**3–4 часа**

---

## Данные — сердце приложения

Без постоянного хранения «Умный список» — блокнот на одном телефоне. В облаке данные живут в **специализированных системах**, каждая со своими компромиссами: консистентность, скорость, стоимость, гибкость схемы.

Архитектор отвечает на вопросы:

1. **Структура** — таблицы, документы, граф?  
2. **Консистентность** — все читают одно и то же сразу?  
3. **Объём и рост** — гигабайты или петабайты?  
4. **Паттерн доступа** — много чтений, редкие записи?

---

## Реляционные БД (SQL)

**PostgreSQL**, **MySQL** — строки в таблицах, связи, транзакции ACID.

| Плюсы | Минусы |
|-------|--------|
| Строгая схема, JOIN | Вертикальное масштабирование write сложнее |
| Транзакции | Миграции при изменении модели |
| Зрелая экосистема | Не идеальны для всех типов данных |

**Учебный кейс:**

```sql
-- Упрощённо
users (id, email)
lists (id, owner_id, title)
items (id, list_id, name, done)
```

Связи `users` → `lists` → `items` естественны для SQL.

---

## Документные БД (NoSQL)

**MongoDB**, **Firestore** — JSON-подобные документы без жёстких JOIN.

| Плюсы | Минусы |
|-------|--------|
| Гибкая схема | Сложнее целостность «как в SQL» |
| Горизонтальный шардинг | Дублирование данных при денормализации |
| Быстрый старт прототипа | Неправильный дизайн — больно мигрировать |

Пример документа «список целиком в одном JSON» — удобно читать одним запросом, тяжело обновлять один пункт при конкуренции.

---

## Выбор SQL vs документ (упрощённо)

| Критерий | Склонность |
|----------|------------|
| Много связей, отчёты | SQL |
| Иерархические документы, редкие связи | Документная |
| Строгие транзакции (деньги) | SQL |
| Очень высокая запись логов | Специализированные TSDB / колоночные |

Для большинства бизнес-приложений **PostgreSQL — разумный default**.

---

## Кэш (Redis, Memcached)

**Кэш** — быстрое **in-memory** хранилище для повторяющихся чтений.

| Сценарий | Пример |
|----------|--------|
| Сессии | `session:abc → userId` |
| Hot keys | Топ-100 списков |
| Rate limit counters | `ip:1.2.3.4:count` |
| Временные блокировки | distributed lock (осторожно) |

```mermaid
flowchart LR
  API[API] --> Cache{Redis?}
  Cache -->|hit| API
  Cache -->|miss| DB[(PostgreSQL)]
  DB --> API
  API -->|записать в кэш| Cache
```

**Важно:** кэш — **не источник правды**. При сбое Redis данные должны восстановиться из БД.

---

## Object Storage (S3-совместимое)

Файлы: аватары, экспорты CSV, бэкапы.

| Свойство | Значение |
|----------|----------|
| Модель | Bucket + key (`/users/42/avatar.png`) |
| Доступ | Публичный URL или signed URL с TTL |
| Метаданные | В БД хранится **ссылка**, не сам файл |

Антипаттерн: BLOB в PostgreSQL для тысяч картинок — дорого и медленно бэкапить.

---

## Поисковые и аналитические хранилища

| Тип | Пример | Когда |
|-----|--------|-------|
| Search | Elasticsearch, OpenSearch | Полнотекстовый поиск по товарам |
| Warehouse | BigQuery, Snowflake | Аналитика, BI |
| Time-series | Prometheus, InfluxDB | Метрики IoT |

Обычно **дополняют** основную БД через ETL или события, не заменяют с нуля.

---

## Managed vs self-hosted

| Managed (RDS, Cloud SQL) | Самостоятельно на ВМ |
|--------------------------|----------------------|
| Патчи, бэкапы от провайдера | Полный контроль |
| SLA и point-in-time recovery | Нужны DBA-навыки |
| Дороже на малых объёмах | Дешевле при огромном тюнинге |

Для обучения и MVP — **managed**.

---

## Репликация и бэкапы (введение)

| Механизм | Зачем |
|----------|-------|
| **Primary + replica** | Чтение с реплик, разгрузка |
| **Point-in-time recovery** | Откат БД на вчера 14:00 |
| **Географическая реплика** | Ближе к пользователям (latency) |

Потеря БД без бэкапа — **катастрофа**; архитектор закладывает RPO/RTO в NFR ([раздел 03](../03-proektirovanie/nfr-i-sla.md)).

---

## CAP (интуиция без формализма)

При сбое сети нельзя одновременно иметь **идеальную** доступность и **мгновенную** согласованность везде. Практика:

- **Банковский перевод** — консистентность важнее  
- **Счётчик лайков** — eventual consistency допустима  

---

## Практика

1. Для учебного кейса: какие сущности в SQL, что в object storage, что в Redis?  
2. Опишите сценарий «кэш устарел» — что видит пользователь и как исправить TTL.  
3. Почему пароли хранят не в открытом виде (намёк на [раздел 05](../05-bezopasnost/sekrety-i-shifrovanie.md))?

---

## Самопроверка

1. Чем object storage отличается от PostgreSQL?  
2. Зачем read replica, если есть один мощный primary?  
3. Почему кэш называют «не источником правды»?

---

## Дальше

→ [Очереди и события](ocheredi-i-sobytiya.md)
