Иммутабельная денормализация
Изучение баз данных всегда сопровождается понятием нормализации, а конкретно первыми тремя формами, которые задают нам ограничения, помогающие правильно разложить все по таблицам. И это действительно база, без которой нормально работать не получится. Но есть, как обычно, нюансы.
В реальных проектах выясняется, что нормализованные данные сложно соединять и выбирать. При глубоком уровне зависимостей, чтобы добраться до внешней сущности, нужно либо соединять 5 таблиц, либо делать 5 запросов. Пример из Хекслета. У нас есть программа обучения, которая состоит из модулей, в которые входят темы которые состоят из уроков, которые состоят из юнитов (теория, практика, тесты). На это все накручено много логики по прогрессу и отображению. В такой структуре, вопросы типа "какой урок следующий по порядку?" заставляют поломать голову.
В таких ситуациях мы начинаем денормализацию данных. В основном она сводится к добавлению внешних ключей на косвенно связанные сущности, например, урок связан с программой обучения через модуль. Здесь мы добавляем ключ на программу прямо из урока, что позволяет выполнять запросы на уроки одной программы без необходимости соединять таблицы.
В принципе это довольно базовая концепция с которой знакомы большинство разработчиков, но дальше начинается самое интересное. Как только мы делаем денормализацию, то сразу упираемся в необходимость синхронизировать данные. Если поменялось в одном месте, надо не забыть поменять и в другом месте. Это цена денормализации и ее надо платить.
> Кстати есть такой концепт как синхронизирующие триггеры, которые вешают только для того, чтобы синхронизировать подобные данные. Когда-то я его активно использовал, но сейчас не стал бы
Но есть и альтернативный подход, который иногда работает лучше. Вместо того, чтобы синхронизировать денормализованные данные, мы можем пересмотреть саму систему и сделать данные иммутабельными (неизменяемыми), чтобы их не нужно было синхронизировать. Например в том же примере с уроками, мы сделали так, что урок принадлежит одной программе и не может перемещаться между программами. А это значит, что мы можем записать в урок все внешние ключи, которые никогда не поменяются. В таком случае цена денормализации это занятое место ключами, чем обычно можно пренебречь.
А что касается бизнес-логики? Да, такой подход работает не всегда, но, как показала практика, его можно использовать намного чаще чем кажется. Например в нашем случае это даже наоборот хорошо, иначе получается ситуация, что при переносе урока нужно переносить прогресс, что значительно усложняет логику и создает странное впечатление, когда в середине программы вдруг появляются пройденные уроки. При этом сама процедура довольно редкая, поэтому если кому-то придется пройти два раза один и тот же урок (перенос в нашем случае это копирование), то ничего страшного не случается.
Но есть места где без синхронизации данных не обойтись никак. В основном это касается статусов, они могут меняться и за ними нужно следить.
p.s. Вы денормализуете данные? Для каких задач?
Telegram |
YouTube |
AI Клуб
Обсуждение 25
Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.
Обсудить в Telegram