Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Chiave esterna per più tabelle

Hai alcune opzioni, tutte variabili in termini di "correttezza" e facilità d'uso. Come sempre, il design giusto dipende dalle tue esigenze.

  • Puoi semplicemente creare due colonne in Ticket, OwnedByUserId e OwnedByGroupId, e avere chiavi esterne nullable per ogni tabella.

  • È possibile creare tabelle di riferimento M:M abilitando sia le relazioni ticket:utente che ticket:gruppo. Forse in futuro vorrai consentire a un singolo biglietto di essere posseduto da più utenti o gruppi? Questo design non impone che un ticket deve essere di proprietà di una sola entità.

  • Puoi creare un gruppo predefinito per ogni utente e avere i ticket semplicemente di proprietà di un vero gruppo o del gruppo predefinito di un utente.

  • Oppure (a mia scelta) modella un'entità che funge da base sia per Utenti che per Gruppi e ha biglietti di proprietà di tale entità.

Ecco un esempio approssimativo utilizzando lo schema pubblicato:

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
)