Проектирование базы данных :: Нормализация в событии с 2 участниками :: Таблица соединения или 2 столбца? - PullRequest
4 голосов
/ 20 мая 2011

Редактировать : обновить обобщенный вопрос, чтобы отразить фактическую область: хоккейный спорт.

Фактическое событие - это расписание игр, а участники - команды.

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

Проблема, обсуждаемая до сих пор в этом потоке, охватывает решение объединить событие в одну строку с 2 столбцами (team1, team2) или разбить на таблицу соединений. До сих пор консенсус таков: придерживайтесь подхода с двумя столбцами. Однако, учитывая, что первоначальный вопрос относился к общим событиям, а не к запланированным играм с соответствующими результатами, в подходе могут быть изменения (например, некоторые могут сказать, что расписание игр должно содержать ОБА информацию о расписании [дата, время, местоположение, команды] и информацию об итогах / результатах игры (счет, ничья выигрыша, ничьи, штрафные минуты и т. д.), и, следовательно, необходимо добавить таблицу соединения для создания уникальных идентификаторов игры.

Ответы до сих пор были отличными; -) Пометится как ответ в ожидании любых обновлений. Спасибо всем!

ОРИГИНАЛЬНЫЙ ВОПРОС:


Озадачен тем, как решить эту проблему.

Каков нормализованный подход к обработке события (происходящего в данную дату и место), когда всегда будет ровно 2 участника?

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

1) eventID PK (autonum)
2) два столбца: участник1 и участник2, PK (автономно) из таблицы участников.

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

Альтернатива, таблица соединения, как я вижу, создаст уникальный идентификатор события вместе с датой, временем и местоположением. Пересмотренная таблица событий будет состоять из объединяющей таблицы eventID и 2 отдельных строк, по одной для каждого участника. При таком подходе я могу легко добавить FK в таблицу событий для memberID (PK из таблицы участников) и, таким образом, иметь надлежащие ограничения.

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


Ответы [ 6 ]

2 голосов
/ 20 мая 2011
  1. Извлеките ограничения из кода приложения и поместите их там, где они должны быть - под контролем БД.

  2. Идентификационные номера не имеют ничего общего снормализация.

  3. Вам нужен стол участников.Установить внешние ключи, ссылающиеся на участников из таблицы событий, с помощью ON DELETE CASCADE;это позволит dbms удалять события, когда пользователи удаляют одного из участников.Это во многом связано с целостностью данных, но никак не связано с нормализацией.

2 голосов
/ 20 мая 2011

Почему вы думаете, что это не нормализовано?Оба идентификатора участника зависят от события таким образом, что оно становится 3NF (в зависимости от ключа, всего ключа и ничего кроме ключа, поэтому помогите мне, Кодд).

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

Events:
    EventId           primary key
    Date
    LocationId        references Locations(LocationId)
    ParticipantOneId  references Participants(ParticipantId)
    ParticipantTwoId  references Participants(ParticipantId)
Locations:
    LocationId        primary key
    <<Other location stuff>>
Participants:
    ParticipantId        primary key
    <<Other participant stuff>>

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

Теперь, если вы когда-либо обнаружили событие, которое может иметь 0, 1, 3 или более участников, вы захотите переработать схему.

До тех пор,YAGNI.

1 голос
/ 20 мая 2011

Не уверен, что вы хотели сохранить данные о статистике игроков на обеих сторонах игры, но предполагали, что вы это делаете.Также предполагается, что возможные местоположения не определены и не особенно важны, поэтому просто сохраните текстовое поле в игровом объекте, чтобы сохранить это.Если вы хотите сообщить о событиях по местоположению , вам следует добавить объект местоположения, чтобы вы могли забронировать игру в определенном месте из списка.Вот базовая модель ER, которая, я думаю, охватывает все ваши установленные правила.Это должно помочь вам прийти к более подробной схеме.«Дневник» или лог-объект хранит разное неструктурированное содержание об игре.например, «Это был дождливый день, и один игрок был удален с поля на 9-й минуте. бла .. бла ...»

enter image description here

1 голос
/ 20 мая 2011

Это выглядит как отношение m-to-n (один человек может создавать / участвовать в нескольких событиях, чтобы в событии могло быть больше участников), поэтому у вас должно быть 3 таблицы:

Таблица События :

  • id - PK - автоинкремент
  • другие сведения (дата начала, продолжительность, местоположение и т. Д.)

Таблица человек :

  • id - PK - автоинкремент
  • другие детали

Таблица person_event :

  • id - PK - автоинкремент (это суррогатный PK, необходимый, потому что таблица содержит дополнительную информацию о человеке и событии)
  • event_id - FK для событий
  • person_id - FK на людей
  • member_role - это может быть организатор, простой участник, почетный гость и т. Д.

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

1 голос
/ 20 мая 2011

Обе ваши схемы нормализованы, в случае, если для каждого события всегда будет два и ровно два участника.

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

1 голос
/ 19 мая 2011

Можете ли вы подробно описать другой вариант, который вы предлагаете?Или это то, что вы просите?Трудно сказать, не зная всех таблиц, но я думаю, что вы делаете это хорошо, тем более что это всегда отношения 1: 2 (игра с командами).Индексируйте по своим идентификаторам (gameId, teamId и т. Д.), И вы будете в порядке, и вам не нужно будет проходить реорганизацию и просто проводить рефакторинг только ради этого.действительно получаешь?

games
=========
game_id PK
game_date
game_time
location

games2teams <-- possibly overkill, since this is a 1-to-2, not 1-to-N or M-to-N
===========    
game_id
team_id

schools
==========
team_id
player_name

results
==========
game_id
team_id
score
...