Masz kilka opcji, wszystkie różniące się „poprawnością” i łatwością użycia. Jak zawsze odpowiedni projekt zależy od Twoich potrzeb.
-
Możesz po prostu utworzyć dwie kolumny w Ticket, OwnedByUserId i OwnedByGroupId, i mieć klucze obce dopuszczające wartość null do każdej tabeli.
-
Możesz utworzyć tabele referencyjne M:M umożliwiające zarówno relacje bilet:użytkownik, jak i bilet:grupa. Być może w przyszłości zechcesz zezwolić na posiadanie jednego biletu wielu użytkownikom lub grupom? Ten projekt nie wymusza, że bilet musi być własnością tylko jednego podmiotu.
-
Możesz utworzyć domyślną grupę dla każdego użytkownika i mieć bilety po prostu należące do prawdziwej grupy lub domyślnej grupy użytkownika.
-
Lub (mój wybór) zamodeluj encję, która działa jako baza zarówno dla użytkowników, jak i grup, i posiada bilety należące do tej encji.
Oto przybliżony przykład użycia opublikowanego schematu:
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
)