【问题标题】:Foreign Key referencing Primary key in the same table外键引用同一张表中的主键
【发布时间】:2017-05-30 06:18:03
【问题描述】:

我有一个包含两列作为主键的表。这两列也是引用同一张表的外键: (这张表是不久前由一个已经离开公司的人创建的)

CREATE TABLE [dbo].[tblItemLink](
    [ItemListID] [int] NOT NULL,
    [ItemID] [int] NOT NULL,
 CONSTRAINT [PK_tblItemList] PRIMARY KEY CLUSTERED 
(
    [ItemListID] ASC,
    [ItemID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[tblItemLink]  WITH CHECK ADD  CONSTRAINT [FK_tblItemLink_tblItemLink] FOREIGN KEY([ItemListID], [ItemID])
REFERENCES [dbo].[tblItemLink] ([ItemListID], [ItemID])
GO

ALTER TABLE [dbo].[tblItemLink] CHECK CONSTRAINT [FK_tblItemLink_tblItemLink]
GO

在实践中,ItemID 指的是 tblItem.ItemID,而 ItemListID 在 DB 中的其他任何地方都找不到,但在应用程序中有相应的枚举。

主键是否有任何理由也是引用自身的外键(即一些未记录的性能改进),还是只是一个错误?

【问题讨论】:

    标签: sql sql-server-2008 foreign-keys


    【解决方案1】:

    我不知道为什么这会带来好处 - 所以我将选择选项 2 - 一个错误。

    当然,如果是同一张表中的不同列,那是有道理的,正如@Jignesh.Raj 指出的那样,这将形成某种层次结构。

    您有时甚至会在同一个表中使用这样的多列引用来结束多个层次结构:

    CREATE TABLE T (
       GroupID int not null,
       ItemID int not null,
       ParentItemID int null,
       constraint PK_T PRIMARY KEY (GroupID,ItemID),
       constraint FK_T_Parent FOREIGN KEY (GroupID,ParentItemID) references T (GroupID,ItemID)
    )
    

    在上面,GroupID 列总是引用自己。

    但正如我所说,对于您当前的表,两个 列仅引用自己,这是没有意义的。

    【讨论】:

    • 只是为了补充这很可能是一个错误的原因:当使用 SSMS 添加新约束时,默认配置是“主键”和“外键”都指当前表的主键。
    【解决方案2】:

    这就是您创建层次结构的方式,并且还可以确保您不能有一个无效父级的子级。

    参见Should you make a self-referencing table column a foreign key?

    【讨论】:

    • 是的,如果有一个外键引用同一个表中的主键,这将是一个层次结构,但在这种情况下,主键是外键 - 所以每一行实际上都是指自己.
    猜你喜欢
    • 2013-09-11
    • 2016-11-18
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多