Как вы нормализуете отношения один-к-одному или другому?
Я храню данные о бейсбольной статистике и хотел бы сделать это с тремя таблицами: Players, BattingStats и PitchingStats. Для цели вопроса у каждого игрока будет статистика ватина или тангажа, но не оба.
Как бы я нормализовал такие отношения в 3NF?
3 ответа
PlayerId будет внешним ключом в таблицах BattingStats и PitchingStats.
[и не забудьте указать некоторое время (сезон, год и т. д.) в таблицах статистики]
и, кстати, это плохое предположение: насколько я знаю, кувшинам тоже разрешается бить!
Вы действительно должны не использовать более 3 таблиц. Обычно нормализация подразумевает разбиение одной ненормализованной модели на множество нормализованных отношений.
Если у вас может быть более 3 таблиц, вы можете рассмотреть следующее (в 3NF):
Players: ([player_id], name, date_of_birth, ...)
Batters: ([batter_id], player_id)
Pitchers: ([pitcher_id], player_id)
Batting_Stats: ([batter_id, time_dimension], stat_1, stat_2, ...)
Pitching_Stats: ([pitcher_id, time_dimension], stat_1, stat_2, ...)
Атрибуты в []
определить первичный ключ, но при необходимости можно использовать суррогатный ключ. player_id
Атрибут в Batters and Pitches должен иметь уникальное ограничение, и он также должен быть внешним ключом для отношения Players. Batting_Stats и Pitching_Stats также должны иметь внешний ключ для Batters и Pitching соответственно.
Тем не менее, обратите внимание, что приведенное выше не означает, что игрок может быть только жидким тестом или кувшином.
ОБНОВИТЬ:
Один из методов, который мне известен, чтобы обеспечить, что игрок - только жидкое тесто или только кувшин, является через эту модель:
Players: ([player_id], name, date_of_birth, ...)
Roles: ([role_id, role_type], player_id)
Batting_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...)
Pitching_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...)
role_type
следует определить кувшин или тесто. Batting_Stats и Pitching_Stats должны иметь составной внешний ключ для ролей, использующих (role_id, role_type)
, Уникальное ограничение на player_id
в ролях будет гарантировать, что игрок может иметь только одну и только одну роль. Наконец, добавьте проверочные ограничения, чтобы Batting_Stats.role_type = 'Batter'
а также Pitching_Stats.role_type = 'Pitcher'
, Эти проверочные ограничения гарантируют, что Batting_Stats всегда описывает тесто, и обратите внимание на кувшин. То же самое относится и к Pitching_Stats.
Я знаю, как бы реализовать это с практической точки зрения (я бы создал UNIONed-представление для непересекающихся таблиц и поместил уникальный индекс в идентификатор игрока - поэтому они могут появляться только в одной таблице).
Или в таблице игроков запишите, какой тип статистики они имеют, а затем включите это в отношение FK из таблиц статистики.
Но любой из них, вероятно, ближе к металлу, чем вы хотите.