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

Нормализация базы данных - кто прав?

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

В качестве примера: Мой профессор утверждает, что этот дизайн прав: (список столбцов)

Subject_ID
Description
Units_Lec
Units_Lab
Total_Units

и т.д...

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

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

student_ID
prelim_grade
midterm_grade
prefinal_grade
average

ЭСТ...

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

Нужно ли мне восстановить мою базу данных (которая состоит из более чем 40 таблиц), чтобы соответствовать тому, что он хочет? Я ошибаюсь и просто упускаю из виду эти вещи?

EDIT:

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

4b9b3361

Ответ 1

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

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

Ответ 2

Вы правы, когда говорите, что ваше решение более нормализовано.

Однако существует вещь, называемая denormalization (google для нее), которая заключается в преднамеренном нарушении правил нормализации для повышения производительности запросов.

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

Для решения потребуется полное сканирование на две таблицы (subject и unit), объединение результатов и сортировка вывода.

Ваше решение для профессора потребовало бы просто взять первые пять записей из индекса на total_units.

Это, конечно, связано с ценой увеличения стоимости обслуживания (как с точки зрения вычислительных ресурсов, так и развития).

Я не могу сказать вам, кто здесь "прав": мы ничего не знаем о самом проекте, томах данных, запросах и т.д. Это решение, которое необходимо принять для каждого проекта (и для некоторых проектов это может быть основным решением).

Дело в том, что у профессора есть обоснование этого требования, которое может быть или не быть справедливым.

Почему он не объяснил вам все вышеизложенное, это еще один вопрос.

Ответ 3

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

Может быть, вы можете использовать вычисленный столбец? Это будет приемлемой средой.

Изменить: Денормализация имеет свое место, , но последняя мера принимает. Это похоже на химиотерапию: врач вводит вас в яд, чтобы вылечить еще большую угрозу вашему здоровью. Это последний возможный шаг.

Ответ 4

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

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

Это редактирование интересно. Основываясь на фактах, что это транзакционная система, обрабатывающая деньги, она должна быть подотчетна. Я беру несколько основных терминов: транзакция, продукт, цена, количество.

В этом смысле это очень часто или даже требуется для денормализации. Зачем? Потому что вам нужно, чтобы он был подотчетен. Поэтому, когда транзакция зарегистрирована, она никогда не может быть изменена. Если вам нужно исправить это, вы выполните другую транзакцию.

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

Таким образом, неприемлемо просто присоединить transaction.product_id = products.id, поскольку этот продукт может измениться. Пример:

2012-01-01 price = 10
2012-01-05 price = 20
Transaction happens here, we sell 10 items so 10 * 20 = 200
2012-01-06 price = 22

Теперь мы просматриваем транзакцию в 2012-01-10, поэтому делаем:

SELECT 
    transactions.amount * products.price AS totalAmount 
FROM transactions 
INNER JOIN products on products.id=transactions.product_id

Это дало бы 10 * 22 = 220, так что это неверно.

Итак, у вас есть 2 варианта:

  • Не разрешать обновления в таблице продуктов. Таким образом, вы делаете эту таблицу версией, поэтому для каждой записи вы добавляете новый INSERT вместо обновления. Таким образом, транзакция продолжает указывать на правильную версию продукта.

  • Или вы просто добавляете поля в таблицу транзакций. Поэтому добавьте totalAmount в таблицу транзакций и вычислите ее (в транзакции базы данных), когда транзакция вставлена ​​и сохраните ее.

Да, он денормализован, но у него есть веская причина, он делает его подотчетным. Вы просто знаете, и он проверял транзакции, блокировки и т.д., Что в тот момент, когда произошла транзакция, это связано с описанным продуктом с ценой = 20 и т.д.

Рядом с этим, и это просто хорошая денормализация, когда вам все равно нужно это делать, очень легко запускать отчеты. Общая сумма транзакции месяца, года и т.д. Все это очень легко рассчитать.

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

См. транзакцию как регистрацию того, что произошло в реальном мире. Это случилось, вы написали это. Теперь вы не можете изменить историю, она была написана так, как была. Будущее не изменит его, это случилось.

Ответ 5

Если вы хотите реализовать хорошую, старую, классическую реляционную модель, я думаю, что вы делаете правильно.

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

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

Дизайн базы данных для реальных приложений вряд ли будет вопросом о том, какие таблицы следует делать. В настоящее время существует множество возможностей для хранения и обработки ваших данных. Существуют реляционные системы, которые все мы знаем и любим, базы данных объектов (например, db4o), объектно-реляционные базы данных (не путать с реляционным сопоставлением объектов, что я имею в виду - такие инструменты, как Oracle 11g с его объектами), базы данных xml (принимать eXist), потоковые базы данных (например, Esper) и существующие в настоящее время базы данных noSQL (некоторые настаивают на том, что их не следует называть базами данных), таких как MongoDB, Cassandra, CouchDB или Oracle NoSQL

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

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

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

Я знаю, что мой ответ - довольно поток совести для сообщения stackoverflow, но я надеюсь, что он не получил как сумасшедший лепту.

Удачи в реляционном перетягивании каната

Ответ 6

Цель нормализации - устранить избыточность, чтобы устранить аномалии обновления, преимущественно в транзакционных системах. Relational по-прежнему является лучшим решением для обработки транзакций, DW, основных данных и многих решений BI. Большинство NOSQL имеют требования к низкой целостности. Таким образом, вы теряете мой твит - раздражающий, но не катастрофический характер. Но потерять мою торговлю в долларах США - большая проблема. Выбор не NOSQL и реляционный. NOSQL делает некоторые вещи очень хорошо. Но Relational никуда не денется. Это по-прежнему лучший выбор для транзакционных, ориентированных на обновление решений. Требования к нормализации могут быть ослаблены, если данные доступны только для чтения или для чтения. Поэтому избыточность не является такой большой проблемой в DW; обновлений нет.

Ответ 7

Здесь вы рассказываете об исторических и финансовых данных. Обычно хранятся некоторые вычисления, которые никогда не изменятся, потому что это затраты, которые были начислены в то время. Если вы делаете расчет из цены продукта *, а цена изменилась через 6 месяцев после транзакции, вы получите неправильное значение. Твой профессор умный, послушай его. Кроме того, если вы делаете много отчетов о базе данных, вы не хотите часто вычислять значения, которые не могут быть изменены без другой записи ввода данных. Зачем выполнять вычисления многократно по истории приложения, когда вам нужно только один раз сделать это? Это расточительство ценных ресурсов сервера.