Máte několik možností, všechny se liší „správností“ a snadností použití. Jako vždy, správný design závisí na vašich potřebách.
-
V Tiketu můžete jednoduše vytvořit dva sloupce, OwnedByUserId a OwnedByGroupId, a pro každou tabulku mít cizí klíče s možnou hodnotou Null.
-
Můžete vytvořit referenční tabulky M:M umožňující vztahy lístek:uživatel i lístek:skupina. Možná v budoucnu budete chtít povolit, aby jeden tiket vlastnilo více uživatelů nebo skupin? Tento návrh nevynucuje, že lístek musí být vlastněn pouze jedním subjektem.
-
Můžete vytvořit výchozí skupinu pro každého uživatele a mít lístky jednoduše vlastněné buď skutečnou skupinou, nebo výchozí skupinou uživatele.
-
Nebo (moje volba) modelovat entitu, která funguje jako základ pro uživatele i skupiny, a mít lístky ve vlastnictví této entity.
Zde je hrubý příklad použití vašeho zaslaného schématu:
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
)