#sql #database-design #foreign-keys #many-to-many
#sql #database-design #внешние ключи #многие ко многим
Вопрос:
Я изучаю SQL и таблицы, внешние ключи и т. Д. Чтобы попробовать это вместо того, чтобы только изучать, я создал 2 таблицы:
Таблица 1: Team
:
Таблица 2: Karakter
(это «символ» на голландском языке)
У команды есть Id ( TeamId
), userId ( GebruikerId
, это пока не важно), name ( Teamnaam
) и CharacterId ( KarakterId
) .
Я хочу, чтобы команда состояла из 3 символов ( karakters
), и я знаю, что могу найти символ с помощью внешних ключей, но, поскольку я хочу 3 символа, а не только 1, мне было интересно, нужно ли в моей таблице указывать KarakterId1, KarakterId2, KarakterId3?
Или вы обычно делаете это другим более простым способом, о котором я не знаю (потому что я не могу его найти)
Заранее спасибо!
Ответ №1:
Это отношение «многие ко многим» между командами и персонажами: когда в одной команде несколько персонажей, и данный персонаж может принадлежать более чем одной команде.
Нормализованный дизайн подразумевает создание третьей таблицы, называемой связующей таблицей, для представления этой взаимосвязи, с одной строкой для каждого кортежа команд / символов, а ограничения внешнего ключа ссылаются на родительские таблицы.
create table teams (
team_id int primary key,
user_id int not null,
name varchar(50)
);
create table characters (
character_id int primary key,
name varchar(50)
);
create table team_characters (
team_id int references teams(team_id),
character_id int references characters(character_id),
primary key (team_id, character_id)
);
Комментарии:
1. И должен ли я вводить в таблицу team_characters 3 раза characterId? Или как иначе он должен знать, что в нем должно быть 3 символа?
2. @LardinoisJ: если в команде 3 символа, это означает 3 строки в таблице мостов с одинаковыми
team_id
и 3 разнымиcharacter_id
именами.
Ответ №2:
Точная вербализация ограничения на естественном языке обычно показывает правильное решение. Вот два возможных примера, их может быть больше.
- Каждый карактер может быть в более чем одной команде; для каждой команды: в этой команде может быть более одного карактера.
karakter {K}
PK {K}
team {T}
PK {T}
team_karakter {T, K}
PK {T, K}
FK1 {K} REFERENCES karakter {K}
FK2 {T} REFERENCES team {T}
- Каждый карактер может состоять более чем в одной команде;
для каждой команды: в этой команде ровно три карактера.
karakter {K}
PK {K}
team {T, K1, K2, K3}
PK {T}
FK1 {K1} REFERENCES karakter {K}
FK2 {K2} REFERENCES karakter {K}
FK3 {K3} REFERENCES karakter {K}
CHECK ((K1 <> K2) AND (K1 <> K3) AND (K2 <> K3))
Примечание:
All attributes (columns) NOT NULL
PK = Primary Key
FK = Foreign Key