Подтвердить что ты не робот

Когда Denormalize дизайн базы данных

Я знаю, что normalis (z) активно обсуждается в Stack Overflow. Я прочитал многие предыдущие обсуждения. Однако у меня есть дополнительные вопросы.

Я работаю над старой системой с не менее чем 100 таблицами. База данных имеет некоторую ненормализованную структуру, таблицы, которые содержат множество разрозненных данных и другие проблемы. Мне поставлена ​​задача улучшить его. Я не могу просто начать снова, но вам нужно изменить существующую схему.

В прошлом я всегда пытался разработать нормализованные базы данных. Теперь вопросы. Старший разработчик предположил, что в некоторых случаях мы не можем нормализовать:

1) С временными данными. Например, создается счет, который ссылается на продукт. Если клиент запрашивает копию этого счета через год, мы должны иметь возможность изготовить точную копию оригинала. Что, если цена продукта, имя или описание были обновлены? Старший парень предложил, чтобы цена и другая информация о товаре были скопированы в таблицу счетов. Я думаю, может быть, у нас должна быть другая таблица, такая как productPrice, у которой есть поле даты, чтобы мы могли отслеживать изменения в цене с течением времени. Нам понадобится то же самое для описания продукта и имени, которое я предполагаю? Кажется сложным. Как вы думаете?

2) База данных - это система учета. Я не очень хорошо разбираюсь в бухгалтерском учете. В настоящее время некоторые сводные данные выводятся и хранятся в базе данных. Например, общий объем продаж за год. Мой старший помощник сказал, что бухгалтеры любят проверять правильность, сравнивая это значение с данными, которые фактически вычисляются из счетов-фактур и т.д., Чтобы дать им уверенность в правильности работы приложения. Он сказал, что на данный момент, например, мы можем сказать, кто-то случайно удалил счет-фактуру с прошлого года, потому что итоговые значения не будут одинаковыми. Он также отметил, что довольно медленно рассчитывать эти итоги "на лету". Конечно, я сказал, что данные не должны дублироваться и всегда должны рассчитываться при необходимости. Я предложил использовать SQL Reporting Services или другое решение, которое будет генерировать эти отчеты в одночасье и кэшировать их. В любом случае он не убедил. Любые комментарии по этому поводу?

Большое спасибо:)
Приветствия
Марк

ИЗМЕНИТЬ

Спасибо за отличные ответы. Жаль, что я могу только отметить это как ответ, потому что здесь есть много хороших предложений.

4b9b3361

Ответ 1

Ваш старший коллега - разработчик, а не модератор данных. Вам лучше начать с нуля, без них. Нормализация осложняется только тем, кто не читает книги, и получает свое "знание" от любителей в вики. Это справедливо, что он заставляет вас думать, но некоторые из вопросов абсурдны.

Ваши номера:

  • Вам необходимо оценить различия между фактическими онлайн-данными и историческими данными; то разница между историческими и архивными потребностями. Все они подходят для конкретного делового требования, а для всех остальных - неправильного, нет универсального права и неправды.

    • Почему нет бумажной копии счета? В большинстве стран, которые были бы юридическими и налоговыми требованиями, какова именно трудность вылавливания старого счета-фактуры?
    • когда в базе данных есть требование хранить закрытые счета-фактуры, тогда обязательно, как только счет будет закрыт, вам нужен способ захвата этой информации.
    • ProductPrice (на самом деле, я бы назвал его ProductDate) - хорошая идея, но может и не понадобиться. Но вы правы, вам нужно оценить валюту данных в полном контексте всей базы данных.
    • Я не вижу, как поможет копирование цены продукта в таблицу счетов (не так ли много позиций?)
    • в современных базах данных, где требуется копирование счета-фактуры, закрытый счет-фактура дополнительно хранится в другой форме, например XML. Один клиент сохраняет PDF файлы как BLOB. Таким образом, нет никаких проблем с тем, что цена продукта была пять лет назад. Но основные данные счета-фактуры являются онлайн-и текущими, даже для закрытых счетов-фактур; вы просто не можете пересчитывать древний счет с использованием текущих цен.
    • некоторые люди используют таблицу archive_invoice, но у этого есть проблемы, потому что теперь каждый сегмент кода или инструмент отчета пользователя должны выглядеть в двух местах (обратите внимание, что в наши дни некоторые пользователи лучше понимают базы данных, чем большинство разработчиков).
    • В любом случае, это все обсуждение, для вашего понимания. Ни одна из баз данных, которые я написал за 30 лет, никогда не сталкивалась с такой проблемой, и все они отвечали требованиям законодательства и налогов.
      • База данных обслуживает текущие и архивные цели из одного набора таблиц (нет "архивных" таблиц
      • После создания счета-фактуры он является юридическим документом и не может быть изменен или удален (его можно отменить или частично зачислить с помощью нового счета-фактуры с отрицательными значениями). Они отмечены IsIssued/IsPaid/Etc
      • Products не могут быть удалены, их можно пометить IsObsolete
      • Существуют отдельные таблицы для InvoiceHeader и InvoiceItem
      • InvoiceItem имеет FKs как InvoiceHeader, так и Product
      • по многим причинам (не только тем, о которых вы упоминаете) строка InvoiceItem содержит NumUnits; ProductPrice; TaxAmount; ExtendedPrice. Конечно, это выглядит как "денормализация", но это не так, потому что цены, ставки налогообложения и т.д. Могут быть изменены. Но что более важно, юридическое требование состоит в том, что мы можем воспроизводить старую фактуру по требованию.
      • (где его можно воспроизвести из бумажных файлов, это не требуется)
      • InvoiceTotalAmount - это производный столбец, просто SUM() для InvoiceItems
        ,
  • Это мусор. Системы бухгалтерского учета и бухгалтеры так не "работают".

    • Если это настоящая система учета, тогда она будет иметь JournalEntries или "двойную запись"; это то, что требуется квалифицированная учетная запись (по закону).

      • Двойной ввод не означает дублирование записи; это означает, что каждая финансовая сделка (одна сумма) должна иметь исходную учетную запись и целевую учетную запись, к которой она применяется; поэтому нет "денормализации" или дублирования. В банковской базе данных, поскольку финансовые транзакции относятся к отдельным учетным записям, которые обычно отображаются как две отдельные финансовые операции (строки) в рамках одной транзакции Db. Обычные ограничения коммерческой базы данных используются для обеспечения наличия двух "сторон" каждой финансовой транзакции.
        .
    • Обеспечение того, что счета-фактуры не подлежат удалению, является отдельной проблемой, связанной с безопасностью и т.д., если кто-либо параноик по поводу вещей, удаляемых из их базы данных, и, их база данных не была защищена квалифицированный человек, тогда у них есть все больше и больше проблем, которые не имеют никакого отношения к этому вопросу. Получите аудит безопасности и сделайте все, что они скажут вам.

    • На этом сайте есть несколько человек, которые считают, что вики - это место, где вы можете чему-то научиться. Это не так. Это выгребная яма "определений", написанная любителями, а "определения" постоянно меняются другими любителями. Нет фиксированного определения, на которое вы можете положиться. Поэтому не беспокойтесь о том, что говорит вики, или о том, что говорят люди в вики, как только они упоминают вики, вы знаете, что их "знание" происходит от чтения без квалификации; и то, что они читают, является постоянно меняющейся выгребной ямой. Они будут предсказуемо спорить о "определениях", поскольку они не имеют реального опыта; опытный будет просто работать с работой

    • Нормализованная база данных всегда намного быстрее, чем ненормализованная база данных. Поэтому очень важно понять, что такое нормализация и денормализация, а что нет. Этот процесс сильно затрудняется, когда у людей есть "текущие" и "любительские" определения, это просто приводит к путанице и "истощению" времени. Когда у вас есть фиксированные определения, вы можете избежать всего этого и просто продолжить работу.

    • Сводные таблицы вполне нормальны, чтобы сэкономить время и мощность обработки, пересчитать информацию, которая не изменяется, например: итоги года с начала года за каждый год, но в этом году; MTD для каждого месяца в этом году, но не в этом месяце. "Всегда пересчитывать" данные немного глупо, когда (а) информация очень большая и (б) не изменяется. Рассчитать только за текущий месяц

      • В банковских системах (миллионы сделок в день) в EndOfDay мы также рассчитываем и сохраняем Daily Total. Они перезаписываются в течение последних пяти дней, потому что Audiitors вносят изменения, и JournalEntries против финансовых транзакций за последние 5 дней разрешены.
      • небанковские системы обычно не нуждаются в ежедневных итогах
        ,
    • Сводные таблицы не являются "денормализацией" (за исключением тех, кто только что узнал о "нормализации" из своего волшебного, постоянно меняющегося жидкого "источника" или как не практикующих, которые применяют простые черно-белые правила ко всему). Опять же, определение здесь не обсуждается; он просто не применяется к Сводным таблицам.

    • Сводные таблицы не влияют на целостность данных (предполагая, конечно, что данные, из которых они были получены, были неотъемлемыми).

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

    • Нет аномалий обновления (это строгое определение), связанных с Сводными таблицами. Вы не можете изменить или удалить счет-фактуру с прошлого года. Аномалии обновления применяются к текущим текущим данным Denormalised или Unnormalised.

Ответ 2

1) Это архив. Все, что в нем, никогда не должно обновляться. Я бы пошел с предложением старшего парня, и эта таблица счетов будет автономной. Возможно, используйте blob для самого счета, который содержит язык разметки?

2) Службы отчетов, таблица хранилища, которая обновляется триггером, что-то, что вы создаете с помощью script, когда... все это будет хорошо, я думаю. Это действительно идеально, чтобы нормализоваться, но это не всегда быстро. У меня есть хорошая база данных здравоохранения, которую я управляю, которая полностью нормализована... и затем имеет серию де-нормированных таблиц с развернутыми уравнениями и обычно вытягиваемыми полями. Почти все исходит из этого ненормированного набора - он просто быстрее добавляет к ним триггер, когда файлы загружаются, чем нужно постоянно извлекать из разных таблиц каждый раз, когда я хочу посмотреть отчет за 100 000 записей.

Ответ 3

Вы поднимаете действительные баллы, однако вы не полностью поняли нормализацию и что это означает, например, в

1) Утверждение о том, что ведение счетов-фактур, поскольку они денормализуют данные, полностью и полностью ошибочно. Например, возьмем цену - если у вас есть бизнес-требование, в котором говорится, что вы должны сохранить историю цен, то сохранение только текущей цены неверно, и это нарушает требования. И это не имеет ничего общего с нормализацией, она просто не разработана хорошо. Денормализация - это введение возможностей двусмысленности в вашу модель (и другие артефакты) - и в этом случае вы просто не моделируете свое проблемное пространство должным образом. Нет ничего плохого в моделировании базы данных для поддержки временных данных (или управления версиями и/или разделения областей базы данных на архив/временную и рабочий набор).

Глядя на нормализацию, не глядя на семантику (с точки зрения требований), невозможно.

Кроме того, если ваш старший разработчик не может видеть разницу, я думаю, что он не получил своего старшинства в разработке РСУБД;)

2) Вторая часть действительно является денормализацией. Тем не менее, если вы когда-нибудь столкнетесь с старшим аналитиком ББ, который серьезно проповедует нормализацию, вы услышите, как он говорит, что вполне приемлемо денормализовать, пока вы это делаете сознательно, и убедитесь, что недостатки избыточного веса и эти аномалии не укусят вас. Они также скажут вам нормализовать логическую модель и что в физической модели вам разрешено отклоняться от идеала для различных целей (производительность, обслуживание и т.д.). В моей книге основная цель нормализации заключается в том, что у вас нет скрытых аномалий (см. Эту статью на 5NF)

Кэширование промежуточных результатов допускается даже в нормализованных базах данных и даже с помощью самых крупных евангелистов нормализации - вы можете сделать это на уровне приложений (как некоторый кеш), или вы можете сделать это на уровне базы данных, или вы можете получить хранилище данных для таких целей. Все они действительны и не имеют ничего общего с нормализацией логической модели.

Кроме того, что касается вашего бухгалтера - вы должны быть в состоянии убедить его, что то, что он утверждает, не является хорошим тестом и разрабатывает набор тестов (может быть, вместе с ним), которые автоматизируют тестирование системы без вмешательства пользователя и дайте вам больше уверенности в том, что ваша система не работает.

С другой стороны, я знаю системы, которые требуют, чтобы пользователи вводили дублируемую информацию, например, чтобы ввести количество строк в счете до или после ввода фактических строк, чтобы гарантировать, что запись будет завершена. Эти данные "дублируются", и вам не нужно их хранить, если у вас есть процедура, которая будет проверять ввод. Если эта процедура приходит позже, ей разрешено хранить "денормализованные" данные - опять же, семантика оправдывает ее, и вы можете посмотреть на модель как нормализованную. (полезно обернуть голову вокруг этой концепции)

EDIT: Термин "денормализованный" в (2) неверен, если вы посмотрите на формальное определение нормальных форм и если вы считаете, что дизайн денормализован, если он нарушает любую из нормальных форм (для некоторых это очевидно, и нет другого пути об этом).

Тем не менее, вы можете привыкнуть к идее, что многие люди и ненужные бесполезные тексты будут использовать термин "нормализация" для любых усилий, которые пытаются уменьшить избыточность в базе данных (как пример, вы найдете научный документы, в которых я не говорю, что они должны быть правы, так же, как предупреждение о том, что это обычное явление, которые вызывают производные атрибуты как форму денормализации, см. здесь).

Если вы хотите обратиться к некоторым более согласованным и признанным авторитетам (опять же, не признанным всеми), возможно, слова C.J.Date могут сделать четкое различие:

Большая часть теории дизайна связана с сокращение избыточности; нормализация уменьшает избыточность в пределах relvars, ортогональность уменьшает его relvars.

qouted из Глубина базы данных: теория реляционных отношений для практиков

и на следующей странице

как неспособность нормализовать все путь подразумевает избыточность и может привести к некоторые аномалии, так и несоблюдение ортогональности.

Таким образом, правильный термин для избыточности через relvars - ортогональность (в основном все нормальные формы говорят об одном ревербе, поэтому, если вы посмотрите строго на нормализацию, он никогда не предложит никаких улучшений из-за зависимостей между двумя разными рельефами).

В любом случае, одна из других важных концепций при рассмотрении дизайна базы данных также является разницей между логическими и физическими моделями баз данных. Многие вещи, которые полезны на физическом уровне, такие как таблицы с промежуточными итогами или индексами, не имеют места в логической модели - где вы пытаетесь установить и исследовать отношения между концепциями, которые вы пытаетесь моделировать. И вот почему вы можете сказать, что они допустимы, и они не разрушают дизайн.

Линии иногда могут быть немного размытыми по логической модели и физической модели. Особенно хорошим примером является таблица с промежуточными итогами. Чтобы считать его частью физической реализации и игнорировать его на логическом уровне, вы должны:

  • гарантировать, что пользователи (и приложения) не могут обновлять таблицу промежуточных итогов напрямую, не соответствующим их предикату (другими словами, есть ошибка в процедуре подтестирования)
  • убедитесь, что пользователи (и приложения) не могут обновить таблицу, на которой они зависят, без обновления промежуточного итога (другими словами, какое-либо приложение не удалит строку из таблицы подробностей без обновления общего количества)

Если вы нарушите любое из вышеуказанных правил, вы получите несогласованную базу данных, которая предоставит противоречивые факты. (В таком случае, если вы хотите формально разработать процедуру для исправления или изучения вызванных проблем, вы не считаете ее просто дополнительной таблицей, она будет существовать на логическом уровне, а там не должно быть).

Кроме того, нормализация всегда зависит от семантики и бизнес-правил, которые вы пытаетесь моделировать. Например, DBAPerformance дает пример, в котором сохранение TaxAmount в таблице транзакций не является денормализованным дизайном, но он не упоминает, что зависит от того, какую систему вы пытаетесь моделировать (это очевидно?); например, если у транзакции есть другой атрибут с именем TaxRate, он обычно будет денормализован, потому что существует функциональная зависимость от набора неключевых атрибутов (TaxAmount = Amount * TaxRate = > FD: Amount, TaxRate → TaxAmount) и один из них следует удалить или гарантировать, что они будут согласованы.

Очевидно, вы могли бы сказать, но если система, которую вы строите, предназначена для аудиторской компании, то у вас может не быть функциональной зависимости - они могут проводить аудит того, кто использует ручные вычисления или имеет неисправное программное обеспечение или должен иметь возможность записывать неполные данные, и расчет может быть ошибочным изначально, и в качестве аудиторской компании вы должны записать факт, как это произошло.

Таким образом, семантика (предикаты), которые определяются требованиями, будут влиять, если какая-либо из нормальных форм нарушена, - влияя на функциональные зависимости (другими словами, правильное установление функциональных зависимостей является весьма важной частью моделирования, когда вы стремитесь к нормализованной базе данных).

Ответ 4

Я согласен с вашим старшим о (1). Строка таблицы транзакций должна фиксировать все состояние в момент транзакции. Период. То, что вы предлагаете, не записывает фактические данные, поэтому оно недопустимо. Я также согласен (2). Независимо от того, что хочет бизнес путем перекрестной проверки, вы должны реализовать. Учет основан на перекрестной проверке, двойном вводе, свертывании бухгалтерских книг и т.д. Вы должны это сделать. Это настолько фундаментально, что вы даже не должны рассматривать его как денормализацию, так же как и выполнение бизнес-требований.

Ответ 5

1) Не требует денормализации. Вам просто нужно определить, какой уровень детализации каждого изменения вам нужно, и сохранить его с помощью соответствующего ключа.

2) Не имеет никакого отношения к денормализации. Сохранение сводных данных не делает денормализацию базы данных. Хранение результатов, полученных из не-ключевых атрибутов в одной и той же таблице, будет примером денормализации, но это не похоже на то, о чем вы здесь говорите.

Ответ 6

Ваш старший разработчик делает чрезвычайно действительные баллы. Я сам это усвоил, обслуживая системы, которые не деформируют исторические данные.

В некотором смысле это не добавляет никаких накладных расходов в базу данных. Вы создаете таблицы счетов из существующих данных в базе данных. Счет-фактура - это моментальный снимок. Де-нормализация информации, необходимой для создания этого счета, может значительно облегчить вашу отчетность. Когда вы должны подготовить новый отчет и, как ожидается, быстро его сделаете, вы по достоинству оцените де-нормализацию.

С точки зрения наличия общего количества в базе данных. Это спасло мою задницу раньше, когда я внес изменения в приложение, которое заставляло номера не складываться одинаково (не так сложно, как вы думаете). В реальном приложении итоговые данные дали мне определенное место, чтобы вернуться, чтобы исправить несоответствия. Я уже писал об этом раньше, вы можете прочитать его здесь: http://jlrand.com/?p=95

Ответ 7

Для # 1

Счет должен быть рассчитан на основе продаж и платежей. Если у вас нет подробных данных о продажах, включая цену/товар/скидку/доставку/etc, отправьте туда.

Для # 2

Написание системы учета в db с нуля - большой проект. Убедитесь, что бухгалтеры предоставляют вам бизнес-правила, чтобы вы могли измерить точность своих систем. Последнее, что вам нужно, - это шаг CFO на встречу DBA и объявление о том, что БД перезаряжает клиента, тем более, что вы недозагружаете и вытесняете компанию из бизнеса.

Если у вас есть SQL Server, вы можете посмотреть в Adventure Works db. Если вы ненавидите MS, посмотрите на Adventure Works и не делайте этого.

Ответ 8

Нормализация базы данных удаляет дубликаты и делает запросы sql для обновления данных более эффективными (и дает некоторые другие улучшения).

Но если большинство ваших запросов используются для выбора данных и выбор запросов к нескольким таблицам в то время, вы можете рассмотреть денормализацию этих таблиц. Это увеличит объем дискового пространства, необходимого для данных, время выполнения запросов на обновление sql, но улучшит выбор запросов.

Ответ 9

Кажется, что вы рассматриваете вопрос об или нет, вы должны создать хранилище данных. Вы никогда не должны денормализовать свою базу данных для целей исторической отчетности. Создание архива и сохранение вашей информации в хранилище данных сделают так: денормализуют большую часть информации и поддерживают историю данных.