Путаница во второй нормальной форме / нормализации: первичный ключ? Составной ключ?

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

Это моя таблица, на которой я сосредоточен MatchDetails:

Идея 1

Попытка составного ключа

ссылка на img

Player_ID - это уникальный первичный ключ для другой таблицы Users. MatchID - это уникальный первичный ключ для таблицы Matches. Отношения между Матчами и Игроками многогранны.

Будет ли это работать как составной ключ? В том смысле, что 1 игрок мог принять участие в конкретном матче только один раз? Имеют ли столбцы справа от MatchID функциональную зависимость от составного ключа в том смысле, что они уникальны для этого составного ключа?

Идея 2

Таблица с первичным ключомссылка на img

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

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

Ну и еще одна мелочь ...

Последнее, в чем я немного сомневаюсь, - это огромное количество столбцов. Вся информация справа от MatchID - это подробности о том, КАК игрок (Player_ID) выступил в матче (MatchID). Должны ли они быть в другой таблице?

Ссылка на другие таблицы, если вы хотите увидеть макет на данный момент: https://i.imgur.com/52ax04g.png

Не обращайте внимания на то, что у MatchID нет символа подчеркивания, а у другого идентификатора есть. Это только тарифный план Excel!


person k4kuz0    schedule 25.02.2014    source источник


Ответы (2)


Если один и тот же игрок не может участвовать в одном матче более одного раза, вам потребуется составной ключ {Player_ID, MatchID}, независимо от того, добавляете ли вы другой ключ (например, {Participation_ID}) или нет. .

Добавление ключа {Participation_ID} имеет смысл только в том случае, если у вас есть другие таблицы, которые ссылаются на него 1, и вы хотите сделать их внешние ключи более тонкими, или если вы используете особенно враждебную ORM, которая требует несоставного первичного ключ.

Имеют ли столбцы справа от MatchID функциональную зависимость от составного ключа

да.

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

Если атрибуты данного ключа являются «аргументами», а остальные атрибуты являются «результатом», то два разных результата не могут быть получены из одних и тех же аргументов просто потому, что ключ уникален и, следовательно, любая конкретная комбинация значения ключевых атрибутов 2 не могут идентифицировать более одного кортежа.

Таким образом, все атрибуты всегда функционально зависят от ключа. Это всегда верно для любого ключа, иначе он не был бы ключом.

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

В вашем случае, если какой-либо из атрибутов зависит от Player_ID только (или только MatchID), это нарушит 2NF.

Последнее, в чем я немного сомневаюсь, - это огромное количество столбцов. Вся информация справа от MatchID - это подробности о том, КАК игрок (Player_ID) выступил в матче (MatchID). Должны ли они быть в другой таблице?

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

Некоторые несвязанные предложения:

  • Используйте согласованное именование: если есть Player_ID, должно быть Match_ID, а не MatchID (или наоборот). Ого, я пропустил ваше последнее предложение.
  • Используйте единственное число для имен таблиц, по той же причине, по которой единственное число обычно используется для имен классов в ООП.

1 Чего вы не видите, насколько я могу судить.

2 Он же. «основные» атрибуты. Как ни странно, первичный атрибут не обязательно должен принадлежать «первичному» ключу (он может принадлежать альтернативному ключу), поэтому просто сказать «ключевые атрибуты», вероятно, будет лучшей терминологией, ИМХО.

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

4 СУБД в наши дни обычно могут обрабатывать сотни или даже тысячи столбцов, и на самом деле это не значит «огромное количество столбцов».

person Branko Dimitrijevic    schedule 25.02.2014
comment
Спасибо за подробный ответ. Я чувствую себя намного яснее в своей проблеме. Если вы это видите, я хотел бы быстро задать кое-что помимо своего основного вопроса. Когда я спросил о переносе некоторых данных в другую таблицу, это потому, что мне кажется, что общее мнение - больше строк, чем больше столбцов. Имея это в виду, будет ли это лучше, чем хранение всех данных в одной таблице? Даже если все эти данные зависят от одного и того же составного ключа. - person k4kuz0; 26.02.2014
comment
@ k4kuz0 Ну, Item_0, Item_1 и т. д. новые - их не было в вашем исходном вопросе. Это подозрительно выглядит как отношение 1: N, которое обычно моделируется с помощью отдельной таблицы. С другой стороны, соотношение 1: 1 обычно моделируется как одна таблица. Кстати, я никогда не слышал о большем количестве строк, чем о консенсусе большего количества столбцов. Я также понимаю, как можно разделить таблицу на отдельные столбцы, чтобы удалить столбцы - во всяком случае, вы продублируете ключ и просто создадите больше столбцов, хотя и распределите их по большему количеству таблиц. - person Branko Dimitrijevic; 26.02.2014
comment
Предметы с 1 по 6 представляют собой слоты, которые есть у игрока (6 слотов предметов), а значения представляют предметы в каждом слоте. Есть и всегда будет всего 6 предметов. Ни больше ни меньше. Что не нарушает 1: N не так ли? Или я не прав? Я понимаю, что вы имеете в виду по поводу столбцов. В таком случае у меня была бы таблица с 23 столбцами, и это нормально? - person k4kuz0; 26.02.2014
comment
@ k4kuz0 Есть и всегда будет только 6 элементов. - в этом случае это не настоящий 1: N, и вы можете просто сохранить явные столбцы. 23 столбца в порядке. - person Branko Dimitrijevic; 26.02.2014

Столбцы {PlayerID, MatchID}, похоже, работают как составной ключ.

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

Если эти столбцы вместо этого представляют общую статистику игроков, то они зависят только от PlayerID, и этот дизайн не входит в 2NF.

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

Не существует такой вещи, как нормальная форма «У меня не слишком много столбцов». Если вам нужно 20 атрибутов, которые функционально зависят от каждого ключа-кандидата, тогда вам нужно 20 атрибутов, которые функционально зависят от каждого ключа-кандидата.

person Mike Sherrill 'Cat Recall'    schedule 25.02.2014
comment
Большое спасибо за ответ! Нет такой вещи, как у меня не слишком много столбцов нормальной формы. Ха-ха, это правда. Однако я видел много ужасных историй о том, что у меня слишком много столбцов, и поэтому пытаюсь понять, как я могу остановить это, прежде чем это станет проблемой! Я задал вопрос об этом вышеупомянутому респонденту, если у вас будет возможность, я буду очень признателен за ответ от кого-то! - person k4kuz0; 26.02.2014
comment
@ k4kuz0 Я видел много ужасных историй .. - Некоторые из них происходят из-за использования ORM, которые не очень гибкий, когда вам нужно только подмножество столбцов. На самом деле это не проблема самой базы данных, а трение, создаваемое инструментами поверх нее. - person Branko Dimitrijevic; 26.02.2014