如何将大量表的主键转换为聚集主键,以保持引用标识

ber*_*d_k 7 sql-server-2005 clustered-primary-key

发现后,我最好将主键从非集群更改为集群。比照有关标识列的聚集索引这个问题,下一步就是如何在prcatical的方式做到这一点。

我很惊讶我没有在 SO 上找到这个问题。

在我的表之间有参考引用,我不能简单地做

if object_id('MyChild') > 0 drop table MyChild
if object_id('Mytable') > 0 drop table Mytable
create table Mytable(
    id int Not NULL
)
go
create table MyChild(
    id int Not NULL,
    masterid int NULL
)
go
alter table Mytable add constraint PK_Mytable primary key  (id)
alter table MyChild add constraint FK_MyChild_MyTable foreign key (masterid) references Mytable(id)
go
-- Now I want to change the primary key into a clustered primary key
-- this throws an error
ALTER TABLE Mytable DROP CONSTRAINT PK_Mytable
GO
ALTER TABLE Mytable ADD CONSTRAINT PK_Mytable  PRIMARY KEY CLUSTERED (id)
GO
Run Code Online (Sandbox Code Playgroud)

在这里我收到以下错误

Msg 3725, Level 16, State 0, Line 1
Auf die 'PK_Mytable'-Einschränkung wird von der 'MyChild'-Tabelle, FOREIGN KEY-Einschränkung 'FK_MyChild_MyTable' verwiesen.
Msg 3727, Level 16, State 0, Line 1
Die Einschränkung konnte nicht gelöscht werden. Siehe vorherige Fehler.
Run Code Online (Sandbox Code Playgroud)

好的,当我在更改之前删除外键约束并在之后重新建立它时,我知道它有效。

alter table MyChild drop constraint FK_MyChild_MyTable
go
ALTER TABLE Mytable DROP CONSTRAINT PK_Mytable
GO
ALTER TABLE Mytable ADD CONSTRAINT PK_Mytable  PRIMARY KEY CLUSTERED (id)
GO
alter table MyChild add constraint FK_MyChild_MyTable foreign key (masterid) references Mytable(id)
go
Run Code Online (Sandbox Code Playgroud)

这听起来像,我必须从数据库中编写所有外键关系的脚本,删除它们,更改主键并从生成的脚本中重新建立外键。

有没有更好的方法来完成这项任务。

顺便提一句。最后,我们希望在生产数据库上执行此操作。(停机时间是允许的选项)。所有数据库都是 SQL Server 2005 或 SQL Server 2008。

编辑:

一位同事提议在此操作之前删除所有索引,然后重建它们。对我来说听起来很合理。

2. 编辑:

看着这个dba.stackexchange问题,我开始问自己是否只将聚集索引添加到表主键列就足够了。

gbn*_*gbn 6

你的方法是正确的,几乎是唯一的方法,但我会考虑使用像 Red Gate 这样的工具来帮助我。

第 3 步省去了编写一些东西来编写我们的 FK 定义的脚本,或摆弄 SSMS/SMO