1. ホーム
  2. sql-server

[解決済み] 複数テーブルへの外部キー

2022-04-22 20:11:53

質問

私のデータベースには、3つの関連するテーブルがあります。

CREATE TABLE dbo.Group
(
    ID int NOT NULL,
    Name varchar(50) NOT NULL
)  

CREATE TABLE dbo.User
(
    ID int NOT NULL,
    Name varchar(50) NOT NULL
)

CREATE TABLE dbo.Ticket
(
    ID int NOT NULL,
    Owner int NOT NULL,
    Subject varchar(50) NULL
)

ユーザーが複数のグループに所属している。 これは多対多の関係で行われますが、この場合は関係ありません。 チケットは、dbo.Ticket.Ownerフィールドを介して、グループまたはユーザーによって所有されることができます。

はどうなるのでしょうか? 最も適切な チケットとユーザーまたはグループとの間のこの関係を記述する方法を教えてください。

チケットテーブルの中に、どのようなタイプが所有しているかというフラグを追加するべきだと考えています。

どのように解決するのですか?

いくつかの選択肢がありますが、どれも正しさや使いやすさはまちまちです。いつものように、正しいデザインはあなたのニーズによって異なります。

  • 単純にTicketにOwnedByUserIdとOwnedByGroupIdという2つのカラムを作成し、それぞれのテーブルに対してNullable Foreign Keysを持つことができます。

  • チケット:ユーザーとチケット:グループの関係を可能にするM:M参照テーブルを作成することができます。おそらく将来的には、1つのチケットを複数のユーザやグループが所有できるようにしたいと思うのではないでしょうか?このデザインは、チケット が必要です。 は、単一のエンティティによってのみ所有されます。

  • すべてのユーザーに対してデフォルトグループを作成し、チケットは単に真のグループまたはユーザーのデフォルトグループのいずれかに所有させることができます。

  • または(私の選択ですが)UsersとGroupsの両方のベースとして機能するエンティティをモデル化し、そのエンティティによってチケットを所有させます。

投稿されたスキーマを使った大まかな例です。

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
)