如何为SQL Server中的表创建一个复合候选密钥



请考虑下表定义...

表定义

CREATE TABLE [dbo].[Folders](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NOT NULL,
    [ParentFolderId] [int] NULL
PRIMARY KEY CLUSTERED 
(
    [Id] 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

其他表与此表[id]的主键列有外键关系。

我希望添加一个自我引用的外键约束,而父文件夹ID引用了同一文件夹表中的另一个记录的ID字段,但是用户ID也必须匹配...

自我引用外键约束

ALTER TABLE [dbo].[Folders]  WITH CHECK ADD  CONSTRAINT [FK_Folders_ParentFolder] FOREIGN KEY([UserId], [ParentFolderId])
REFERENCES [dbo].[Folders] ([UserId], [Id])
GO
ALTER TABLE [dbo].[Folders] CHECK CONSTRAINT [FK_Folders_ParentFolder]
GO

...但是我遇到了错误...

错误

Msg 1776, Level 16, State 0, Line 64
There are no primary or candidate keys in the referenced table 'dbo.Folders' that match the referencing column list in the foreign key 'FK_Folders_ParentFolder'.
Msg 1750, Level 16, State 0, Line 64
Could not create constraint or index. See previous errors.
Msg 4917, Level 16, State 0, Line 67
Constraint 'FK_Folders_ParentFolder' does not exist.
Msg 4916, Level 16, State 0, Line 67
Could not enable or disable the constraint. See previous errors.

我试图在表中添加一个复合唯一索引以提供候选密钥,但这仍然不起作用,我仍然会遇到相同的错误。

唯一索引

CREATE UNIQUE NONCLUSTERED INDEX [IX_Folders_UserParentFolder] ON [dbo].[Folders]
(
    [UserId] ASC,
    [ParentFolderId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

如何在[Id][UserId]上创建超键/候选密钥,以便我可以添加自引用外键?请记住,将主键从单个整数转换为复合键会破坏引用文件夹表的其他表上的外键。这些外键不需要意识到用户ID。

编辑:

根据丹·古兹曼(Dan Guzman(添加数据库约束的建议/评论可以做到这一点。这是约束的定义...

约束定义

ALTER TABLE [dbo].[Folders]
ADD CONSTRAINT AK_Folders_UserId UNIQUE ([UserId], [Id])
GO

外键列引用的列必须是主键,唯一约束或唯一索引。我在这里建议一个独特的约束:

ALTER TABLE dbo.Folders
ADD CONSTRAINT UQ_Folders_UserId_Id UNIQUE(UserId, Id);

最新更新