О нормализации и денормализации данных
Одним из ключевых моментов проектирования баз данных является нормализация данных — устранение избыточности информации, при которой каждый факт должен храниться только в одном месте. Аспекты нормализации данных исследованы и разработаны уже достаточно давно как с методологической, так и с математической стороны.
И все вроде бы хорошо: приводи базу как минимум к третьей нормальной форме и будет всем счастье. ) Однако всегда есть НО...
Нельзя сказать, что понятие нормализации устарело. Я думаю и надеюсь, вы со мной согласитесь, нормализация была, есть и будет важным моментом проектирования баз данных. Без нее в базах данных, во всяком случае, реляционных, будет хаос. Однако давайте вспомним, что основным принципом нормализации является разбиение таблиц на более мелкие, обладающие лучшими свойствами добавления, удаления и редактирования данных. А это означает, что увеличивается количество таблиц, приходится вводить искусственные первичные и внешние ключи, выполнять индексацию и устанавливать по ключам связи между таблиц. То есть вместо выборки данных из одной таблицы приходится собирать их по разным таблицам. В принципе, ничего страшного в этом нет, кроме необходимости хорошего знания команды select языка SQL и различных видов join-ов.
Однако в последнее время положение дел стремительно меняется. Предметные области усложняются, количество сущностей, описывающих предметную область, увеличивается, а с применением нормализации, их число возрастает как минимум в 2-3 раза. Объемы хранимой информации постоянно растут, таблицы с десятками и сотнями тысяч записей никого не удивляют. В современных СУБД все больше появляются и активно используются специализированные типы данных (например, универсальные уникальные идентификаторы UUID, xml, json, геометрические типы), которые могут занимать большие объемы памяти. Сами таблицы уже не хранятся в одной папке одного диска, а могут быть распределены по нескольким дискам, находящимся на разных серверах. В результате, выборка и анализ данных из таких таблиц становится уже дорогостоящим занятием. Объединение распределенных таблиц с большим количеством записей и объемными полями может занимать большое количество времени и ресурсов.
В связи со всем вышеизложенным, на передний план все чаще выходит понятие денормализации данных. Процесс, обратный нормализации, когда приходится объединять данные в одну таблицу или добавлять дополнительные поля. Такие действия сразу же ведут к появлению избыточности данных, но позволяют уменьшить затраты на получение информации.
Важным моментом денормализации является то, что она используется НЕ вместо нормализации, а ПОСЛЕ ее. Здесь нужно найти золотую середину: до каких пор мы можем разбивать данные, чтобы облегчить выполнение команд insert, update и delete, и когда можно допустить некоторую избыточность для ускорения выполнения команды select.
Если подходить к вопросу с точки зрения конечного пользователя, то временные затраты на выполнение запросов играют первостепенную роль. В таком случае, группировка данных по каким-то признакам и хранение их в сводных таблицах является обоснованным решением. В зависимости от частоты выполнения запросов и обновления данных, сводные таблицы можно реализовывать как в виде физических, так и в виде временных таблиц или представлений. Такие таблицы, безусловно, будут денормализованными, однако, если данные в них формируются из нормализованных таблиц, и пользователь не имеет возможности их редактирования, то это вполне приемлемый вариант. Даже при необходимости предоставления прав редактирования сводных таблиц, реализовать проверку целостности данных можно через навешивание на них триггеров или через внешние процедуры.
Часто в таблицы приходится добавлять поля, хранящие результаты выполнения агрегатных функций. Они очень сильно помогают в формировании итоговых сводных отчетов. Подобные действия также приводят к нарушению нормализации данных, но это не сильно критично, особенно если поля являются вычисляемыми или проверяются опять-таки соответствующими триггерами.
Вопрос нормализации/денормализации будет еще долго открытым. До недавних пор я сам был приверженцем строго нормализованных баз данных. Однако возможность ощутимого повышения производительности и упрощение выполнения select-ов привели меня к пониманию того, что денормализация данных при аккуратной реализации не зло, а объективная необходимость. Что мне нравится в проектировании баз данных, так это то, что есть четко проработанные инструменты, но нет идеальных решений на все случаи жизни, а значит, всегда есть место для творчества и движения вперед.