Что интересно в этой теме вопросов и ответов, так это то, что на самом деле есть 3 вопроса. Все ответили по-разному, и почти никто не ответил на первый:
- Почему не некоторые базы данных в дикой природе нормализовались?
- Почему / когда нормализованная база данных должна быть денормализована ?
- В каких ситуациях это в первую очередь вредно или не нужно нормализовать?
Внимательные читатели заметят, что это очень разные вопросы, и я постараюсь ответить на каждый из них отдельно, избегая при этом слишком большого количества деталей. Под «слишком большим» я подразумеваю, что я не думаю, что это подходящий контекст, в котором следует проводить расширенные дебаты по поводу достоинств различных аргументов в пользу или против нормализации; Я просто собираюсь объяснить, что это за аргументы, возможно, перечислю несколько предостережений и оставлю философию для более конкретных вопросов, если они когда-нибудь возникнут.
Кроме того, в этом ответе я предполагаю, что «нормализация» подразумевает «BCNF, 3NF или, по крайней мере, 2NF» , поскольку это уровень нормализации, который обычно стремятся достичь разработчики. Реже можно увидеть дизайн 4NF или 5NF; хотя они, безусловно, не являются невозможными целями, они озабочены не только их представлением , но и семантикой отношений , что требует значительно большего знания предметной области.
Итак, вперед и вверх:
1. Почему некоторые базы данных в дикой природе не нормализуются?
Ответом на это может быть «потому что они не должны быть», но сделать такое предположение сразу же - это довольно бедная детективная работа. Мы не достигли бы большого прогресса в обществе, если бы всегда действовали исходя из того, что все должно быть.
Реальные причины, по которым базы данных не нормализуются в первую очередь, более сложны. Вот лучшие 5, с которыми я столкнулся:
Разработчики, которые проектировали это , не знали или не понимали, как нормализовать. Убедительным доказательством этого является множество других сопутствующих неудачных вариантов дизайна, таких как использование столбцов varchar для всего или наличие спагетти-беспорядка бессмысленных имен таблиц и столбцов . И я вас уверяю, я видел «настоящие» базы данных, которые ничуть не хуже, чем в статьях TDWTF.
Разработчикам, которые его разработали, было все равно или они активно выступали против нормализации в принципе . Обратите внимание, здесь я не говорю о случаях, когда было принято преднамеренное решение не нормализоваться на основе контекстного анализа, а о командах или компаниях, где нормализация более или менее понятна, а просто игнорируется или избегается по привычке. Опять удивительно часто.
Программное обеспечение было / было сделано как проект Brownfield . Многие пуристы игнорируют этот совершенно законный бизнес, а не техническую причину не нормализации. Иногда на самом деле вам не удается спроектировать новую базу данных с нуля, вы должны использовать существующую унаследованную схему, и попытка нормализации на этом этапе потребует слишком много боли. 3NF не был изобретен до 1971 года, и некоторые системы - особенно финансовые / бухгалтерские системы - имеют свои корни еще дальше!
Первоначально база данных была нормализована , но накопление небольших изменений за длительный период времени и / или широко распространенная команда представили тонкие формы дублирования и другие нарушения любой нормальной формы, которая изначально была на месте. Другими словами, потеря нормализации была случайной , и слишком мало времени было потрачено на рефакторинг.
Было принято преднамеренное деловое решение не тратить время на бизнес-анализ или разработку базы данных, а просто «сделать это». Это часто ложная экономика и в конечном итоге становится растущей формой технического долга , но иногда это рациональное решение, по крайней мере, на основе информации, которая была известна в то время - например, база данных, возможно, была задумана как прототип, но в конечном итоге быть продвинутым к производственному использованию из-за нехватки времени или изменений в деловой среде.
2. Почему / когда нормализованная база данных должна быть денормализована?
Это обсуждение часто появляется , когда база данных будет нормализована , чтобы начать с. Либо производительность низкая, либо в запросах (объединениях) много дублирования, и команда чувствует, правильно или ошибочно, что они продвинулись настолько далеко, насколько это возможно с текущим дизайном. Важно отметить, что нормализация повышает производительность в большинстве случаев, и есть несколько вариантов устранения избыточных объединений, когда нормализация работает против вас, многие из которых менее инвазивны и рискованны, чем просто переход на денормализованную модель:
Создайте индексированные представления, которые инкапсулируют наиболее распространенные проблемные области. Современные СУБД способны сделать их вставляемыми или обновляемыми (например, INSTEAD OF
триггеры SQL Server ). Это требует небольших затрат на операторы DML в базовых таблицах / индексах, но, как правило, это первый вариант, который вы должны попробовать, потому что его практически невозможно испортить и почти ничего не стоит обслуживать. Конечно, не каждый запрос можно превратить в индексированное представление - агрегированные запросы являются наиболее проблемными. Что приводит нас к следующему пункту ...
Создайте денормализованные таблицы агрегирования, которые автоматически обновляются триггерами. Эти таблицы существуют в дополнение к нормализованным таблицам и образуют своего рода модель CQRS . Другая модель CQRS, более популярная в наши дни, заключается в использовании pub / sub для обновления моделей запросов, что дает преимущество асинхронности, хотя это может не подходить в очень редких случаях, когда данные не могут быть устаревшими.
Иногда индексированные представления невозможны, скорости транзакций и объемы данных слишком велики, чтобы допускать триггеры с приемлемой производительностью, и запросы всегда должны возвращать данные в реальном времени. Эти ситуации редки - я бы рискнул предположить, что они могут относиться к таким вещам, как высокочастотная торговля или базы данных правоохранительных органов / разведки - но они могут существовать. В этих случаях у вас действительно нет другого выбора, кроме как денормализовать исходные таблицы.
3. В каких ситуациях нормализовать вредно или нет необходимости?
На самом деле, здесь есть несколько хороших примеров:
Если база данных используется только для отчетности / анализа. Как правило, это подразумевает, что для OLTP используется дополнительная нормализованная база данных, которая периодически синхронизируется с базой данных анализа посредством ETL или обмена сообщениями.
При применении нормализованной модели потребовался бы излишне сложный анализ поступающих данных. Примером этого может быть система, которая должна хранить телефонные номера, которые собраны из нескольких внешних систем или базы данных. Вы можете денормализовать код вызова и код города, но вам придется учитывать все возможные форматы, недопустимые номера телефонов, туалетные номера (1-800-GET-STUFF), не говоря уже о разных локалях. Обычно это больше проблем, чем стоит, и телефонные номера обычно просто помещаются в одно поле, если только у вас нет особой бизнес-потребности в коде города.
Когда реляционная база данных в первую очередь предназначена для обеспечения поддержки транзакций для дополнительной нереляционной базы данных. Например, вы можете использовать реляционную базу данных в качестве очереди сообщений или для отслеживания статуса транзакции или саги, когда первичные данные хранятся в Redis, MongoDB или чем-то еще. Другими словами, данные являются «контрольными данными». Обычно нет смысла нормализовывать данные, которые на самом деле не являются бизнес-данными .
Сервис-ориентированные архитектуры, которые совместно используют физическую базу данных. Это немного странным один, но в истинном SOA, вы будете время от времени необходимо иметь данные физически дублируется , поскольку услуги не могут напрямую запрашивать данные друг друга. Если они случаются , чтобы делить ту же физическую базу данных, данные будут отображаться не будут нормализованы - но , как правило, данные , принадлежащие каждой отдельной услуги является еще нормализованы , если один из других смягчающих факторов не на месте. Например, службе выставления счетов может принадлежать объект счета, но службе учета необходимо получать и хранить дату и сумму счета, чтобы включить ее в доход за этот год.
Я уверен, что есть больше причин, которые я не перечислил; По сути, я понимаю, что они весьма специфичны и будут достаточно очевидны, когда они появятся на практике. Предполагается, что в базах данных OLAP используются схемы типа «звезда», SOA должны иметь некоторое дублирование и т. Д. Если вы работаете с хорошо известной моделью архитектуры, которая просто не работает с нормализацией, то вы не нормализуетесь; Вообще говоря, модель архитектуры имеет приоритет над моделью данных.
И ответить на самый последний вопрос:
Правда ли, что хорошие архитекторы и эксперты выбирают денормализованный дизайн, а неопытные разработчики - наоборот? Каковы аргументы против запуска вашего проекта с учетом нормализации?
Нет, это полная и полная BS Это также BS, что эксперты всегда выбирают нормализованный дизайн. Эксперты не просто следуют мантре. Они исследуют, анализируют, обсуждают, уточняют и повторяют, а затем выбирают подход, наиболее подходящий для их конкретной ситуации.
База данных 3NF или BCNF обычно является хорошей отправной точкой для анализа, поскольку она была опробована и доказана как успешная в десятках тысяч проектов по всему миру, но опять же, как и в случае с C. Это не означает, что мы автоматически используем C в каждом новый проект. В реальных ситуациях могут потребоваться некоторые модификации модели или использование другой модели в целом. Вы не знаете, пока не окажетесь в такой ситуации.