Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Fremdschlüssel zu mehreren Tabellen

Sie haben einige Optionen, die sich alle in "Korrektheit" und Benutzerfreundlichkeit unterscheiden. Wie immer hängt das richtige Design von Ihren Bedürfnissen ab.

  • Sie könnten einfach zwei Spalten in Ticket erstellen, OwnedByUserId und OwnedByGroupId, und jede Tabelle mit nullbaren Fremdschlüsseln versehen.

  • Sie könnten M:M-Referenztabellen erstellen, die sowohl Ticket:Benutzer- als auch Ticket:Gruppen-Beziehungen ermöglichen. Vielleicht möchten Sie in Zukunft zulassen, dass ein einzelnes Ticket mehreren Benutzern oder Gruppen gehört? Dieses Design erzwingt nicht, dass ein Ticket muss Eigentum nur einer einzigen Entität sein.

  • Sie könnten eine Standardgruppe für jeden Benutzer erstellen und Tickets entweder einer echten Gruppe oder der Standardgruppe eines Benutzers gehören lassen.

  • Oder (meine Wahl) eine Entität modellieren, die als Basis für Benutzer und Gruppen fungiert, und Tickets besitzen, die dieser Entität gehören.

Heres ein grobes Beispiel mit Ihrem geposteten Schema:

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
)