2012-05-26 2 views
13

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

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

Subject_ID 
Description 
Units_Lec 
Units_Lab 
Total_Units 

и т.д ...

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

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

student_ID 
prelim_grade 
midterm_grade 
prefinal_grade 
average 

ЭСТА ...

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

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

EDIT:

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

+3

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

+0

@ redskins80 прямо здесь. Однако следует отметить, что никогда не рекомендуется слишком много спорить с вашим профессором, если вы хотите получить хороший класс в своем классе. Как бы он ни ошибался ... –

+0

Andomar прямо на этом. Делайте то, что нужно, чтобы сделать оценку. Но когда вы выходите на собеседование (см. Мой комментарий ниже), убедитесь, что вы правильно ответили на этот вопрос. –

ответ

11

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

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

+1

Согласен с @ redskins80; есть некоторые случаи, когда полезно денормализовать данные, но только как оптимизацию в тех случаях, когда вам это нужно часто, и очень дорого ее вычислять каждый раз из своих источников. – lanzz

+2

Единственное возможное исключение в этом случае - и я немного растягиваю * попытку *, чтобы дать этому профессору какую-то выгоду от сомнений, - если по бизнес-правилам в системе Total_Units не всегда есть чтобы равняться сумме двух других столбцов ... скажем, например, если Total_Units могут включать бонусные единицы, присужденные по усмотрению профессора, который не понимает нормализацию базы данных. :-) –

+0

@ KP Тейлор: ОЧЕНЬ ДЕЙСТВИТЕЛЬНАЯ ТОЧКА Я должен сказать! может быть возможным, за исключением того, что студент должен был знать, было ли это так. Он не спросил бы об этом иначе. – arijeet

6

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

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

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

+0

... или создать представление в таблице, содержащей столбец Total. –

+1

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

+1

Еще хуже: каждый раз, когда изменяется строка, следует пересчитать средние значения ** всех строк **. – wildplasser

1

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

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

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

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

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

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

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

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

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

+0

Спасибо, я сделаю то, что ты сказал. Кстати, мы используем sql-сервер. – Arman

12

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

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

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

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

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

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

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

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

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

+0

Я знаю о денормализации перед запуском проекта и не думал, что это принесет пользу системе. Обоснование моего профессора таково: 1. Мнения могут быть удалены случайно. 2. Дебет/кредит должны быть перечислены соответственно. (Напротив, просто запрашивать прошлые транзакции) – Arman

+0

@Arman: какой ответ вы ожидаете от нас? Является ли ваше решение более нормализованным - да, это так. Является ли ваше решение более эффективным - мы не знаем и не можем сказать из-за ограниченного объема предоставленных данных. Кто прав - «му». – Quassnoi

+2

Отличный ответ. Если нормализацией было все, все базы данных были бы в 5-й нормальной форме, и вы вряд ли когда-либо смогли бы выяснить проблемы, которые происходят с программой, без написания огромного SQL-запроса с несколькими объединениями. Я работал над системами, которые были чрезмерно нормализованы, и это была настоящая PITA. Между нормализацией и простотой использования существует хорошая промежуточная точка. –

4

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

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

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

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

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

Так что неприемлемо просто вступить в транзакцию.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 

Теперь мы LookUp сделку в 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 варианта:

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

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

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

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

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

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

1

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

1

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

+0

«Ваш предисер умный»? Возможно, ему повезло, что он оказался прав в этой конкретной проблеме. Хотя, конечно, IIRC, вы могли бы решить проблему с исторической ценой/таблицей продуктов и основывать общую сумму платежей на то, что обычно является большой проблемой для прохождения, поэтому часто используются фактические суммы платежей. – reiniero

+0

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

+0

@reiniero, даже транзакционные базы данных имеют отчетность о них. Я говорю о вещах, которые не нужны; часто меняя и применяя это, база данных лучше для производительности, чем вычисление, особенно если вычисление означает, что вы получите неверный answeer, поскольку текущая цена не является ценой, которая была начислена. Временные данные являются специальными в проекте datbase. Это не денормализация, чтобы делать такой расчет по временным данным, чтобы иметь отчет о том, что было начислено во время транзакции. – HLGEM

Смежные вопросы