【问题标题】:Foreign key reference to a specific subtype对特定子类型的外键引用
【发布时间】:2015-07-25 12:22:03
【问题描述】:

这个问题来自Foreign Key to multiple tables 但我认为我的阐述可以使用它自己的主题。

假设我有以下架构(改编自上述链接中的@Nathan Skerl's 答案):

    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 NOT NULL,
    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 NOT NULL,
    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 NOT NULL,
    [Owner] int NOT NULL references dbo.Party(PartyId),
    [Subject] varchar(50) NULL
)

假设我有另一个关系,比如“Stuff”,其中“Users”可以拥有许多“Stuff”项目,但“Groups”拥有“Stuff”没有意义。我可以在“东西”引用中有一个外键只是“用户”吗?

如果有可能,那么如何去做呢?还是我必须直接通过“派对”来完成我所有的那种外键? 我自己尝试时遇到错误(引用的表“dbo.Users”中没有与外键中的引用列“ID”匹配的主键或候选键)。

提前致谢!

【问题讨论】:

    标签: sql sql-server relational-database supertype


    【解决方案1】:

    如果我理解正确,你可以做你想做的事。这个想法是在PartyTypeId, Id 上创建一个唯一的密钥。

    CREATE TABLE dbo.[User] (
        ID int NOT NULL,
        Name varchar(50) NOT NULL,
        PartyTypeId as cast(1 as tinyint) persisted,
        foreign key (ID, PartyTypeId) references Party(PartyID, PartyTypeID),
        unique (PartyTypeId, Id)
    );
    
    CREATE TABLE Stuff (
        StuffId int not null primary key,
        UserId int,
        PartyTypeId as cast(1 as tinyint)  persisted,
        Foreign Key (UserId) references user(PartyTypeId, userId)
    );
    

    Here 是一个 SQL Fiddle。 这在documentation 中有解释。

    【讨论】:

    • 感谢您提供非常有帮助的答案以及所附链接。也帮助了我的理解。几件事:上面的代码与 Fiddle 不匹配;事实上,上面的代码生成了一个“外键引用列的数量与引用列的数量不同,表'Stuff'。”错误。
    • 其次,我想知道仅在 User 中的 ID 字段上断言唯一性的利弊,然后让 Stuff 中的 FK 只是 UserId 字段(因此删除 PartyTypeId 字段)跨度>
    【解决方案2】:

    是的,您可以在 Stuff 中使用外键引用只是用户:

    CREATE TABLE Stuff (
        StuffId int not null primary key,
        UserId int,
        Foreign Key (UserId) references dbo.[User](ID)
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2014-02-09
      • 1970-01-01
      • 2021-09-06
      • 2018-04-01
      • 2018-06-19
      • 1970-01-01
      相关资源
      最近更新 更多