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

16

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

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

Мысли об этом?

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

stoogemuffin
источник
6
Почему так? похоже, здесь хорошо.
Ли Риффель
Вопрос, который я хочу задать, заключается в том, спрашиваете ли вы о нормализации или о реальных потребностях производства? Для производства я бы спросил, если это действительно так?
Jcolebrand

Ответы:

14

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

Table: game_titles

game_title                      year_first_released
--
The first game                  1998
The second game                 1999
Best game: the third one        2001
The fourth game                 2003
Forty-two, the end of games     2011

Вы оцениваете, находится ли он в 2NF, задавая себе эти вопросы.

Q: Прежде всего, это в 1NF?

A: Да, это так.

Вопрос: Каковы основные атрибуты (атрибуты, которые являются частью ключа-кандидата)?

A: "game_title" является единственным основным атрибутом.

Q: Каковы непростые атрибуты?

A: "year_first_released" является единственным.

Q: Функционально "year_first_released" зависит от всего "game_title" или только от его части?

A: Единственный ключ-кандидат "game_title" - это один столбец; у него даже нет частей. Таким образом, year_first_released функционально зависит от всего game_title.

Вуаля. Вы нашли 2NF.

Вы можете прорезать некоторые формальные термины, сначала спросив, есть ли он в 1NF, а затем ответив на этот вопрос.

Q: Существуют ли какие-либо ключи-кандидаты?

A: Нет.

Вуаля. Вы снова нашли 2NF.

По определению, для таблицы, которая нарушает 2NF, она должна иметь как минимум один ключ-кандидат, имеющий более одного столбца.

Вот ваши причины отклонить мнение вашего друга.

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

Ни одна из этих причин не имеет никакого отношения к тому, находится ли таблица в 2NF.

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

О, и та таблица с двумя столбцами, которую я предоставил выше - это в 5NF.

Майк Шеррилл 'Cat Recall'
источник
2
Красиво сделано. У меня было соблазн опубликовать ответ, в котором ничего не говорилось, кроме вашего первого предложения ... «Другой разработчик базы данных просто неправ», вы очень хорошо раскрыли причину.
Марк Стори-Смит
5

Создание отдельной таблицы для любого атрибута не имеет ничего общего с нормализацией. 2NF, 3NF, BCNF, 4NF, 5NF занимаются устранением неключевых зависимостей. Если вы удалите какой-либо отдельный атрибут в новую таблицу и замените его атрибутом внешнего ключа, то зависимости в таблице логически будут такими же, как и раньше, поэтому пересмотренная версия таблицы не более или менее нормализована, чем она. был раньше.

nvogel
источник
Я хочу кое-что добавить к этому, но не уверен что. Вы говорите, что перемещение чего-либо в таблицу с корреляцией 1: 1 (либо 1 ключ к точно 1 значению, как в данном случае, либо от одной строки к одной строке) не дает никакой выгоды, если поиск не нужен, верно? Но есть потенциальная выгода для поиска, если вам редко нужен год, и вы смотрите только на диапазон 255 лет или меньше. Можно предположить, что здесь есть несколько сохраненных байтов, но так как обычно они выделяются по 4 байта, это не является разумным предположением.
Jcolebrand
1
@jcolebrand: согласен с тем, что ты говоришь. Тем не менее, ответ на этот вопрос один и тот же: независимо от того, делаете ли вы это или нет, нормализация сама по себе не имеет никакого отношения.
nvogel
Я согласен. Как я уже сказал, мое слово было нерешительным "Я чувствую, что ОП здесь что-то упустил" ... потому что я не уверен, куда идти с этой концепцией.
Jcolebrand
5

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

Эта таблица будет содержать определение (реальная дата начала и окончания) финансового года

a_horse_with_no_name
источник
1
+1 вам нужен стол, только если он будет иметь атрибуты :)
Джек Дуглас
2

От http://en.wikipedia.org/wiki/Second_normal_form :

таблица 1NF находится в 2NF тогда и только тогда, когда, учитывая любой ключ-кандидат K и любой атрибут A, который не является составной частью ключа-кандидата, A зависит от всего K, а не только от его части.

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

На практическом уровне плохая идея отделять год по всем перечисленным вами причинам.

Ли Риффель
источник
2

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

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

Аргумент может быть другим для таблицы календаря, где каждая строка представляет день и может иметь другие атрибуты (день недели, смещение UTC, будь то праздник и т. Д.).

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

WHERE othertable.year = 2011

Вместо того

WHERE dt >= 20110101 AND dt < 20120101

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

Аарон Бертран
источник
1

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

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

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

Альфа
источник