8kb*_*8kb 9 index sql-server primary-key sql-server-2008-r2
我正在使用从 MS Access 导入的旧数据库。在 MS Access > SQL Server 升级过程中创建了大约 20 个带有非集群唯一主键的表。
其中许多表还具有唯一的非聚集索引,它们是主键的副本。
我正在尝试清理它。
但是我发现在我将主键重新创建为聚集索引,然后尝试重建外键后,外键引用了旧的重复索引(这是唯一的)。
我知道这一点,因为它不会让我删除重复的索引。
我认为 SQL Server 会始终选择一个主键,如果存在的话。SQL Server 是否有在唯一索引和主键之间进行选择的方法?
要复制问题(在 SQL Server 2008 R2 上):
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Child') DROP TABLE Child
GO
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Parent') DROP TABLE Parent
GO
-- Create the parent table
CREATE TABLE Parent (ParentID INT NOT NULL IDENTITY(1,1))
-- Make the parent table a heap
ALTER TABLE Parent ADD CONSTRAINT PK_Parent PRIMARY KEY NONCLUSTERED (ParentID)
-- Create the duplicate index on the parent table
CREATE UNIQUE NONCLUSTERED INDEX IX_Parent ON Parent (ParentID)
-- Create the child table
CREATE TABLE Child (ChildID INT NOT NULL IDENTITY(1,1), ParentID INT NOT NULL )
-- Give the child table a normal PKey
ALTER TABLE Child ADD CONSTRAINT PK_Child PRIMARY KEY CLUSTERED (ChildID)
-- Create a foreign key relationship with the Parent table on ParentID
ALTER TABLE Child ADD CONSTRAINT FK_Child FOREIGN KEY (ParentID)
REFERENCES Parent (ParentID) ON DELETE CASCADE NOT FOR REPLICATION
-- Try to clean this up
-- Drop the foreign key constraint on the Child table
ALTER TABLE Child DROP CONSTRAINT FK_Child
-- Drop the primary key constraint on the Parent table
ALTER TABLE Parent DROP CONSTRAINT PK_Parent
-- Recreate the primary key on Parent as a clustered index
ALTER TABLE Parent ADD CONSTRAINT PK_Parent PRIMARY KEY CLUSTERED (ParentID)
-- Recreate the foreign key in Child pointing to parent ID
ALTER TABLE Child ADD CONSTRAINT FK_Child FOREIGN KEY (ParentID)
REFERENCES Parent (ParentID) ON DELETE CASCADE NOT FOR REPLICATION
-- Try to drop the duplicate index on Parent
DROP INDEX IX_Parent ON Parent
Run Code Online (Sandbox Code Playgroud)
错误消息:
消息 3723,级别 16,状态 6,第 36 行 索引“Parent.IX_Parent”上不允许显式 DROP INDEX。它用于 FOREIGN KEY 约束强制执行。
(缺乏)文档表明此行为是一个实现细节,因此未定义且随时可能更改。
这与CREATE FULLTEXT INDEX形成鲜明对比,您必须指定要附加到的索引的名称 - AFAIK,没有未记录的FOREIGN KEY
语法来执行等效操作(尽管理论上,将来可能会有)。
如前所述,SQL Server 选择与外键关联的最小物理索引确实有意义。如果您更改脚本以将唯一约束创建为CLUSTERED
,则该脚本在 2008 R2 上“有效”。但该行为仍未定义,不应依赖。
与大多数遗留应用程序一样,您只需要深入了解细节并进行清理。