Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Clé étrangère vers plusieurs tables

Vous avez quelques options, toutes variant en "exactitude" et en facilité d'utilisation. Comme toujours, le bon design dépend de vos besoins.

  • Vous pouvez simplement créer deux colonnes dans Ticket, OwnedByUserId et OwnedByGroupId, et avoir des clés étrangères nullables pour chaque table.

  • Vous pouvez créer des tables de référence M:M permettant à la fois les relations ticket:user et ticket:group. Peut-être souhaiterez-vous à l'avenir autoriser qu'un seul ticket appartienne à plusieurs utilisateurs ou groupes ? Cette conception n'impose pas qu'un ticket doit être la propriété d'une seule entité.

  • Vous pouvez créer un groupe par défaut pour chaque utilisateur et faire en sorte que les tickets appartiennent simplement à un vrai groupe ou au groupe par défaut d'un utilisateur.

  • Ou (mon choix) modéliser une entité qui agit comme une base pour les utilisateurs et les groupes, et avoir des tickets appartenant à cette entité.

Voici un exemple approximatif utilisant votre schéma posté :

create table dbo.PartyType
(   
    PartyTypeId tinyint primary key,
    PartyTypeName varchar(10)
)

insert into dbo.PartyType
    values(1, 'User'), (2, 'Group');


create table dbo.Party
(
    PartyId int identity(1,1) primary key,
    PartyTypeId tinyint references dbo.PartyType(PartyTypeId),
    unique (PartyId, PartyTypeId)
)

CREATE TABLE dbo.[Group]
(
    ID int primary key,
    Name varchar(50) NOT NULL,
    PartyTypeId as cast(2 as tinyint) persisted,
    foreign key (ID, PartyTypeId) references Party(PartyId, PartyTypeID)
)  

CREATE TABLE dbo.[User]
(
    ID int primary key,
    Name varchar(50) NOT NULL,
    PartyTypeId as cast(1 as tinyint) persisted,
    foreign key (ID, PartyTypeId) references Party(PartyID, PartyTypeID)
)

CREATE TABLE dbo.Ticket
(
    ID int primary key,
    [Owner] int NOT NULL references dbo.Party(PartyId),
    [Subject] varchar(50) NULL
)