Моделирование данных и индексы

Как превратить требования в таблицы/коллекции и не забыть про индексы под горячие запросы.

Денормализация — намеренное дублирование данных ради скорости чтения, в обмен на усложнение записи; частый приём в read-heavy системах.

От сущностей к схеме

Выпишите основные сущности и связи между ними. Для мини-соцсети это User, Post, Follow, Like. Покажите ключевые поля и связи, не уходя в каждую колонку.

User(id, name, created_at)
Post(id, author_id -> User, text, created_at)
Follow(follower_id -> User, followee_id -> User)
Like(user_id -> User, post_id -> Post)

Индексы под запросы

Главный приём: смотрите на горячие запросы и под них ставьте индексы. «Лента пользователя» -> нужен индекс по (author_id, created_at), чтобы быстро брать свежие посты автора. Без индекса БД делает полное сканирование, и под нагрузкой это узкое место.

ЗапросИндекс
Посты автора по дате(author_id, created_at)
Лайки поста(post_id)
На кого подписан юзер(follower_id)

Нормализация против денормализации

Нормализованная схема (без дублей) экономит место и упрощает запись, но требует JOIN на чтении. В read-heavy системах часто денормализуют: например, хранят like_count прямо в Post, чтобы не считать лайки каждый раз. Это ускоряет чтение ценой аккуратного обновления счётчика при записи.

Как работает под капотом

Индекс — это отдельная отсортированная структура (обычно B-дерево), позволяющая находить строки без полного сканирования. Платите за него двумя вещами: местом на диске и замедлением записи (каждый INSERT/UPDATE обновляет индексы). Поэтому индексы ставят прицельно под горячие запросы, а не на все колонки подряд. Денормализация — это, по сути, «материализованный» ответ на частый запрос, который вы поддерживаете вручную.

Частые ошибки

  • Спроектировать схему, не посмотрев на запросы к ней.
  • Навесить индексы на всё подряд и убить производительность записи.
  • Денормализовать там, где данные часто меняются и счётчики разъезжаются.

Итог

  • Модель данных выводится из горячих запросов, а не наоборот.
  • Индексы ставьте прицельно под частые запросы; они замедляют запись.
  • Денормализация ускоряет чтение ценой ручной поддержки согласованности.
Проверьте себя
1. От чего в первую очередь зависит выбор индексов?
AОт числа таблиц
BОт горячих (частых) запросов к данным
CОт имени базы данных
DОт количества пользователей
2. Чем приходится платить за денормализацию (например, хранение like_count в Post)?
AЗамедлением чтения
BУсложнением записи: счётчик нужно аккуратно обновлять
CПотерей всех данных
DНевозможностью использовать индексы