8.4 SQL Server唯一索引
SQL Server唯一索引(Unique Index)
简介
唯一索引确保索引键列不包含重复值。
唯一索引可以由一列或多列组成。如果唯一索引有一列,则此列中的值将是唯一的。如果唯一索引有多个列,则这些列中的值组合是唯一的。
任何试图向唯一索引键列中插入或更新数据而导致重复的行为都会报错。
唯一索引可以是聚集索引或非聚集索引。
要创建唯一索引,可以使用CREATE UNIQUE INDEX
语句,如下所示:
CREATE UNIQUE INDEX index_name
ON table_name(column_list);
示例
A)创建包含一列的唯一约束
通过邮件caren.stephens@msn.com
查找客户:
SELECT
customer_id,
email
FROM
sales.customers
WHERE
email = 'caren.stephens@msn.com';
查询优化器必须扫描整个聚集索引才能找到该行。
为了加快查询速度,可以在电子邮件(email
)列添加非聚集索引。
但是,假设每个客户都有唯一的电子邮件,您可以为电子邮件列创建唯一索引。
由于sales.customers
表已经有数据了,所以要先检查电子邮件列中的重复值:
SELECT
email,
COUNT(email)
FROM
sales.customers
GROUP BY
email
HAVING
COUNT(email) > 1;
查询返回一个空结果集。说明电子邮件列中没有重复的值。
因此,可以直接为sales.customers
的电子邮件列创建唯一索引:
CREATE UNIQUE INDEX ix_cust_email
ON sales.customers(email);
现在,查询优化器将走ix_cust_email
索引,并使用索引查找
(Index Seek
)方法搜索行。
B)创建包含多列的唯一约束
首先,创建一个名为t1的表,其中有两列:
CREATE TABLE t1 (
a INT,
b INT
);
接下来,创建一个包含a列和b列的唯一索引:
CREATE UNIQUE INDEX ix_uniq_ab
ON t1(a, b);
然后,在t1表中插入新行:
INSERT INTO t1(a,b) VALUES(1,1);
然后,在t1表中插入另一行。请注意,值1在a
列中重复,但a
列和b
列中的值组合不重复:
INSERT INTO t1(a,b) VALUES(1,2);
正常插入,没有问题
最后,将已经存在的行插入t1表中:
INSERT INTO t1(a,b) VALUES(1,2);
SQL Server报错如下:
Cannot insert duplicate key row in object 'dbo.t1' with unique index 'ix_ab'. The duplicate key value is (1, 2).
SQL Server唯一索引与NULL
NULL
是特殊的。是一个标记,表示没有数据或者数据不适用。
NULL
甚至不等于它本身。但是,当涉及到唯一索引时,SQLServer会对NULL
值进行相同的处理。这意味着如果在一个可为NULL
的列上创建唯一索引,则此列中只能有一个NULL
值。
以下创建名为t2
的新表,并在a
列上定义唯一索引:
CREATE TABLE t2(
a INT
);
CREATE UNIQUE INDEX a_uniq_t2
ON t2(a);
在a列中插入NULL:
INSERT INTO t2(a) VALUES(NULL);
但是,如果再次执行上述查询,SQL Server会因重复的NULL
值而报错:
INSERT INTO t2(a) VALUES(NULL);
唯一索引(Unique index)与唯一约束(UNIQUE constraint)
唯一索引和唯一约束都强制一列或多列中值的唯一性。
SQL Server以相同的方式验证唯一索引和唯一约束的重复项。
创建唯一约束时,SQL Server会在幕后创建与此约束关联的唯一索引。
但是,对列创建唯一约束可以明确唯一索引的作用。