Sql server 2012 定义主键约束时指定现有的非聚集唯一索引
我有一个堆表-未定义聚集索引-(称之为Sql server 2012 定义主键约束时指定现有的非聚集唯一索引,sql-server-2012,primary-key,non-clustered-index,Sql Server 2012,Primary Key,Non Clustered Index,我有一个堆表-未定义聚集索引-(称之为表a),在不可为空的列上有一个唯一的非聚集索引(称之为列ID和索引IX) 在为表A定义列ID上的主键约束时,我想使用索引IX 某个地方的文档说明了这一点: 数据库引擎自动创建唯一索引,以强制执行主键约束的唯一性要求。如果聚集索引 表上不存在或未显式指定非聚集索引,将创建唯一的聚集索引以强制主键约束 我已经阅读了整个altertable文档,但似乎没有“非聚集索引是……明确指定的”的语法 已经尝试定义非聚集的索引IX并指定主键,还尝试了alter table的
表a
),在不可为空的列上有一个唯一的非聚集索引(称之为列ID
和索引IX
)
在为表A
定义列ID
上的主键约束时,我想使用索引IX
某个地方的文档说明了这一点:
数据库引擎自动创建唯一索引,以强制执行主键约束的唯一性要求。如果聚集索引
表上不存在或未显式指定非聚集索引,将创建唯一的聚集索引以强制主键约束
我已经阅读了整个altertable
文档,但似乎没有“非聚集索引是……明确指定的”的语法
已经尝试定义非聚集的索引IX
并指定主键,还尝试了alter table的各种组合。。。添加约束。。。主键语句无效
当我在alter表中简单地指定ID列时,我的索引IX相当于SQL Server创建的非聚集索引,这是有意义的。。。。添加约束。。。。主键(ID)语句,但我不希望使用SQL Server为我创建的这个冗余索引,而是让它使用索引IX
,它还包括列的include列表
如果我删除SQL Server创建的索引,那么主键约束也将消失
如果可以更改SQL Server创建的索引,我的问题将得到解决,但我希望对其进行的更改需要删除并重新创建。无法创建约束并将其与已保证约束的现有索引关联 此功能确实存在于其他RDBMS中。它对于超类型/子类型模式特别有用,因为这需要在
Id
和(Id,Type)
上创建唯一的索引,即使后者(FK所需的)在逻辑上由第一个模式保证
可以使用altertable将唯一索引替换为唯一约束,作为仅元数据的更改。。。切换
,但尝试对非聚集PK约束执行相同操作失败
ALTER TABLE SWITCH语句失败。中没有相同的索引
目标表“B”中索引“IX”的源表“A”
为唯一约束执行此操作的代码是
初始位置
用唯一约束替换唯一索引
为什么不让桌子保持原样呢?具有
非空
和唯一
约束的列相当于具有主键
约束的列。为什么要更改它呢?文档不清楚。我认为这意味着根据语句创建聚集索引或非聚集索引。并不是说您可以指定以前存在的索引。因此,在定义主键
约束时,您无法避免创建一个新索引。我猜他们指的是主键声明中主键
后面的可选[CLUSTERED | NONCLUSTERED]
部分(这可能也是@ypercube所说的)。语法图无法指定要与主键约束一起使用的现有索引,您只能指定[新]主键索引是群集索引还是非群集索引。不能保持表的原样-需要主键才能在其他表上具有外键约束,参考相关表格。还可以不让sql server做它自己的事情并创建索引,因为自动创建的索引并不完全是必需的-例如,希望在索引上有一些include列。现在,我只需要创建冗余索引就可以了。这并不理想,因为在DML语句中需要维护多个索引,多个索引会让查询优化程序感到困惑:-),并且会浪费更多的内存。是的,Andrey M,我同意,他们可能指的是指定非聚集索引或不指定非聚集索引的能力(与指定实际的现有索引不同:-)但是,他们应该重新措辞。谢谢你。
CREATE TABLE dbo.A(ID INT NOT NULL, OtherCols VARCHAR(200));
CREATE UNIQUE NONCLUSTERED INDEX IX ON dbo.A(ID);
INSERT INTO dbo.A VALUES (1,'A'),(2,'B');
SET XACT_ABORT ON;
BEGIN TRAN;
CREATE TABLE dbo.B
(
ID INT NOT NULL CONSTRAINT IX UNIQUE NONCLUSTERED,
OtherCols VARCHAR(200)
);
ALTER TABLE dbo.A
SWITCH TO dbo.B;
DROP TABLE dbo.A;
EXECUTE sp_rename
N'dbo.B',
N'A',
'OBJECT';
COMMIT;