Как называется операция переноса данных из нескольких таблиц в одну для оптимизации запросов
Что проверяют
Знаете ли вы термин «денормализация» и, главное, понимаете ли её цену: кто и как будет держать скопированные данные в актуальном виде. Следом обычно спрашивают, как вы синхронизируете копию и почему не хватило индекса.
Как отвечать
Коротко назовите термин: денормализация, то есть осознанное дублирование данных из нескольких таблиц в одну, чтобы читающий запрос обходился без JOIN или без агрегации на лету.
Дальше покажите, что знаете формы:
- дублирующая колонка: в
ordersлежитcustomer_name, и список заказов строится одной таблицей; - счётчик:
posts.comments_countвместоCOUNT(*)по комментариям на каждый показ; - материализованное представление: в PostgreSQL
CREATE MATERIALIZED VIEWиREFRESH MATERIALIZED VIEW CONCURRENTLY, которому нужен уникальный индекс. Данные отстают до следующего обновления; - отдельная модель чтения: read model в CQRS, витрина в ClickHouse или документ в Elasticsearch, собранный из нескольких сущностей.
Затем главное: синхронизация. Копию можно обновлять в той же транзакции (db.BeginTx(ctx, nil), два ExecContext, tx.Commit()), триггером в базе или событием через transactional outbox и консьюмер, который обновляет модель чтения. Первые два способа дают строгую согласованность в пределах одной базы, outbox даёт eventual consistency, и это надо проговорить вслух.
Для счётчиков в Go важна деталь: обновлять атомарно в SQL, UPDATE posts SET comments_count = comments_count + 1 WHERE id = $1, а не читать значение в структуру, прибавлять и писать обратно. Второй вариант при конкурентных запросах теряет инкременты.
Где спотыкаются
Называют операцию «слиянием», «ETL» или «джойном». JOIN соединяет таблицы в запросе, а вопрос про то, как данные хранятся.
Перечисляют плюсы и забывают про аномалии обновления: имя клиента поменялось, а в старых заказах висит прежнее. Иногда это как раз желаемое поведение (снимок на момент заказа), и сильный ответ это различает.
Денормализуют без замеров. Сначала нужен EXPLAIN ANALYZE: медленный запрос часто лечится составным индексом, и тогда дублирование приносит только лишнюю работу по синхронизации.