又来说一下顺序~关于唯一索引和唯一约束的顺序

本文通过实验探讨了SQL中唯一约束与唯一索引的执行优先级问题,包括同一字段上的唯一索引与唯一约束、不同字段上的唯一约束与唯一索引,以及组合唯一约束的效果。

上次说了同一个对象里面不同触发器的执行顺序。今天我也想分享一些我在同一个表里面,建上不同的唯一约束,不同的唯一索引,看下结果会怎样

首先简单建个测试表,不多,就4列

CREATE TABLE AAA3 (ID INT IDENTITY(1,1),Col1 VARCHAR(50),Col2 VARCHAR(50),Col3 VARCHAR(50))

情况1:然后往Col1 都添加上唯一索引和唯一约束。然后插入同样的数据,看下提示信息报那个先

CREATE UNIQUE INDEX UQ_AAA3_Col1 ON AAA3(Col1)
ALTER TABLE dbo.AAA3 ADD CONSTRAINT UQ_AAA3_Col1_1 UNIQUE(Col1)

INSERT INTO dbo.AAA3
        (  Col1, Col2, Col3 )
VALUES  ( N'1', N'',N''  )

GO 2


开始执行循环

(1 行受影响)
消息 2601,级别 14,状态 1,第 9 行
不能在具有唯一索引“UQ_AAA3_Col1”的对象“dbo.AAA3”中插入重复键的行。重复键值为 (1)。
语句已终止。
** 在执行批处理期间遇到错误。正在继续。
批处理执行已完成 2 次。

出错是肯定的,但是可以看到,出错信息是显示唯一索引 UQ_AAA3_Col1 而并非唯一约束创建的索引 UQ_AAA3_Col1_1 。这里大概可以知道是在同一个字段里面比较,唯一索引比唯一约束要优先。(当然谁那么无聊……)

情况2:然后我尝试了一下在不同的列上面建唯一约束和唯一索引,看下是哪个比较优先,用在本例子,就是 Col2 创建唯一约束, Col3 创建唯一索引

ALTER TABLE dbo.AAA3 ADD CONSTRAINT UQ_AAA3_Col2_1 UNIQUE(Col2) 
CREATE UNIQUE INDEX UQ_AAA3_Col3 ON AAA3(Col3)

INSERT INTO dbo.AAA3
        (  Col1, Col2, Col3 )
VALUES  ( N'2', N'',N''  )

消息 2627,级别 14,状态 1,第 9 行
违反了 UNIQUE KEY 约束“UQ_AAA3_Col2_1”。不能在对象“dbo.AAA3”中插入重复键。重复键值为 ()。

确实报唯一索引的抛出出的错。(我怀疑过,是因为Column_id 前后的关系吗?然而不是,即使我在Col2 建唯一索引,Col3 建唯一约束,结果也是一样。唯一约束的判定优先)。

情况3 :将情况2 的约束索引+情况1 的唯一索引都干掉,新增一个组合唯一索引查看效果。把Col1,Col2 组成组合唯一约束,看下效果是哪个好

ALTER TABLE dbo.AAA3 ADD CONSTRAINT UQ_AAA3_Col1_2 UNIQUE(Col1,Col2)


INSERT INTO dbo.AAA3
        (  Col1, Col2, Col3 )
VALUES  ( N'1', N'',N''  )

消息 2627,级别 14,状态 1,第 9 行
违反了 UNIQUE KEY 约束“UQ_AAA3_Col1_2”。不能在对象“dbo.AAA3”中插入重复键。重复键值为 (1, )。

这个例子看出,符合唯一约束优先检测~so,我想到的情况就是这个样纸了~

 

PS:有时觉得研究这些问题可能是没有什么实际应用场景~但是还是需要脑洞一下了~聊此一笑呵呵

 

转载于:https://www.cnblogs.com/Gin-23333/p/5250479.html

### 普通索引与唯一索引的数据结构及实现方式 #### 数据结构差异 普通索引唯一索引在底层数据结构上的设计基本相同,都是基于B树或其变种(如B+树)。这类树形结构允许快速定位记录并支持高效的范围查询操作。然而,在功能特性方面两者存在显著区别。 对于普通索引而言,它并不限制被索引字段内的重复值;也就是说,多个不同的记录可以拥有相同的索引项[^1]。这意味着在同一棵索引树中可能存在多条路径指向具有相同比较键值的不同行记录。 相比之下,唯一索引则强制要求所覆盖的每一列组合下的值在整个表内必须独一无二。当创建了一个唯一索引来约束某几列时,数据库管理系统会在内部确保任何试图违反这一规则的操作都将失败——无论是通过拒绝插入新纪录还是阻止修改现有记录来达成此目的。 #### 实现方式对比 从物理层面看,两种类型的索引都依赖于额外构建的一套有序列表来加速访问速度。这套列表包含了原始表格中的部分信息以及指向实际存储位置的指针。具体来说: - **普通索引**:仅需维护一个按指定顺序排列的关键字集合及其对应的地址映射关系即可; - **唯一索引**:除了上述工作外还需要执行额外逻辑用于验证待加入的新成员是否已经存在于当前体系之中,并据此决定接受与否。 ```sql -- 创建普通索引的例子 CREATE INDEX idx_name ON table(column); -- 创建唯一索引的例子 CREATE UNIQUE INDEX unique_idx_name ON table(unique_column); ``` #### 性能考量 尽管二者在查询性能上表现相近,但在涉及写入操作(即`INSERT`, `UPDATE`, 或者 `DELETE`) 的场景下,由于唯一性校验的存在会使唯一索引带来一定的开销增加。每当向设置了唯一索引的表里添加新的记录之前,系统都要先检查即将录入的信息是否会破坏已有的独特性质[^3]。 因此建议尽可能采用普通索引除非业务需求明确规定某些字段应保持全局唯一性。这样做不仅有助于简化架构同时也能够提升整体处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值