将非群集PK重建为群集PK?

时间:2015-01-02 13:27:06

标签: sql-server database sql-server-2008-r2

对于具有NON集群PK的Products表,根本没有集群索引:是否可以使用ALTER INDEX..REBUILD(或任何简单方法)将NON CLUSTERED PK更改为{{1}一个?怎么样? 我很乐意避免使用DROP,因为还有其他表限制阻止我丢弃产品PK。


编辑:
我发现使用 TOAD for SQL Server (我有免费的社区版),我可以右键单击一个表,选择Alter Table,将Clustered从False更改为True生成一个可怕但工作的脚本,它创建一个新表,复制数据,删除并重新创建/重命名它所需的一切。
但是,我仍然希望有一种推荐的方法来使用特殊工具

2 个答案:

答案 0 :(得分:3)

您可以使用DROP_EXISTING = ON选项创建聚簇索引。如果您愿意,也可以通过这种方式创建主键。


BEGIN TRAN

SELECT *
INTO o
FROM sys.objects

CREATE UNIQUE NONCLUSTERED INDEX sjhfg ON o (object_ID)
CREATE UNIQUE CLUSTERED INDEX sjhfg ON o (object_ID) WITH (DROP_EXISTING = ON)

SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('o')

ROLLBACK

答案 1 :(得分:2)

大多数文章/答案表明这是不可能的。但是,如@usr的答案所示,可以将NonClustered索引转换为Clustered索引。由于我们正在处理PK,因此需要:

  • 首先删除引用此PK的所有FK
  • 忽略PK的约束部分,只需将PK的索引部分重新创建为UNIQUE CLUSTERED
  • 最后,重新创建在步骤1中删除的所有FK

如果这是一个非常大的表,你无法承受这个表被锁定的时间,或者你无法承担在这个操作发生时相关表上发生的操作的孤立数据的可能性,你应该这样做以下内容减少了切换所需的时间:

  1. 使用群集PK
  2. 创建名为[CurrentName_new]的重复表
  3. 迁移数据
  4. 删除并重新创建从属表上的FK以指向新表
  5. 将当前表重命名为[CurrentName_old]
  6. 将新表重命名为[CurrentName]