当我希望列具有不同的值时,我可以使用约束

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

或者我可以使用唯一的索引

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

具有独特约束的列似乎是独特索引的好候选者。

是否有任何已知的理由使用唯一的约束并且不使用唯一的索引?

有帮助吗?

解决方案

在引擎盖下,独特的约束与唯一索引相同 - 需要一个索引来有效地满足执行约束的要求。即使由于独特的约束而创建索引,查询计划者也可以像其他任何索引一样使用它,如果将其视为处理给定查询的最佳方法。

因此,对于支持这两种功能的数据库,使用的选择通常会归结为首选样式和一致性。

如果您打算将索引用作索引(即,您的代码可能依赖于该字段上的搜索/排序/过滤以快速),我将明确使用唯一索引(并评论源),而不是限制来使其做到这一点清晰 - 这样 - 如果在以后的应用程序(或其他编码器)的后续修订中更改了唯一性要求,以确保将非唯一索引置于唯一的索引(只需删除独特的约束将删除)索引完全)。此外,特定的索引也可以在索引提示中命名(即带有(index(ix_index_name))),我认为对于在管理唯一性的幕后创建的索引并非如此,因为您不太可能知道其名称。

同样,如果您只需要执行唯一性作为业务规则,而不是需要搜索或用于排序的字段,那么我会使用约束,再次使预期的使用更加明显。

请注意,如果您同时使用唯一约束和唯一索引,则数据库将不足以看到重复,因此您最终将获得两个索引,这些索引将消耗额外的空间并减慢行插入/更新。

其他提示

除其他答案中的要点外,这是两者之间的一些关键差异。

注意:错误消息来自SQL Server 2012。

错误

违反唯一约束返回错误2627。

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

违反唯一索引返回错误2601。

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

禁用

独特的约束不能被禁用。

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

但是,可以禁用主密钥约束或唯一约束背后的唯一索引,任何唯一的索引也可以被禁用。 帽子尖脑2000。

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

请注意,通常警告禁用聚类索引使数据无法访问。

选项

独特的约束支持索引选项,例如 FILLFACTORIGNORE_DUP_KEY, ,尽管并非每个版本的SQL Server都如此。

包括列

非集群索引可以包括非索引列(称为覆盖索引,这是一个主要的性能增强)。主密钥和唯一约束背后的索引不能包括列。 帽子尖头@ypercube。

过滤

独特的约束无法过滤。

可以过滤唯一的索引。

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

外国钥匙限制

外键约束不能引用过滤的唯一索引,尽管它可以引用非过滤的唯一索引(我认为这是在SQL Server 2005中添加的)。

命名

创建约束时,指定约束名称是可选的(对于所有五种约束)。如果您没有指定名称,则MSSQL将为您生成一个名称。

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

创建索引时,必须指定名称。

帽子 @i-One。

链接

http://technet.microsoft.com/en-us/library/aa224827(V=SQL.80).aspx

http://technet.microsoft.com/en-us/library/ms177456.aspx

引用MSDN作为权威来源:

创建独特的约束和创建独立于约束的唯一索引之间没有显着差异. 。数据验证以相同的方式进行,并且查询优化器不会区分由约束或手动创建的唯一索引。但是,在列上创建独特的约束使索引的目的明确... 更多信息在这里

和...

数据库引擎会自动创建一个唯一的索引来强制唯一约束的独特性要求。 因此,如果尝试插入重复行,则数据库引擎会返回错误消息,该消息说明唯一约束已违反,并且不会将行添加到表中。除非明确指定聚类索引,否则默认情况下创建了独特的非聚集索引来执行唯一的约束... 更多信息在这里

另一个进入: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx

唯一约束和唯一索引之间的主要区别之一是,对另一表的外键约束可以参考构成独特约束的列。对于唯一的索引并非如此。此外,唯一的约束被定义为ANSI标准的一部分,而索引不是。最后,被认为存在于逻辑数据库设计领域的独特约束(可以通过不同的DB引擎以不同的方式实现),而索引是物理方面。因此,独特的约束更为声明。在几乎所有情况下,我都希望独特的约束。

在Oracle中,主要区别是您可以创建一个函数唯一索引,该索引无法使用唯一的约束:

例如

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

所以 fk_xyz 仅在具有的记录中 amount != 0.

独特的约束优于唯一索引。当约束不是唯一的时,您需要使用常规或非唯一索引。约束也是另一种类型的索引。索引用于更快的访问速度。

唯一的索引可以具有条款的位置。例如,您可以根据日期列为每年创建索引

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top