唯一约束和检查约束

UNIQUE 约束和 CHECK 约束是两种类型的约束,可用于在 SQL Server 表中强制实施数据完整性。 这些是重要的数据库对象。

本主题包含以下各节:

UNIQUE 约束

CHECK 约束

相关任务

UNIQUE 约束

约束是 SQL Server 数据库引擎为你强制执行的规则。 例如,可以使用 UNIQUE 约束来确保不会在未参与主键的特定列中输入重复值。 尽管 UNIQUE 约束和 PRIMARY KEY 约束都强制实施唯一性,但当你希望对不是主键的列或列组合的唯一性进行强制时,请使用 UNIQUE 约束而不是 PRIMARY KEY 约束。

与 PRIMARY KEY 约束不同,UNIQUE 约束允许值为 NULL。 但是,与任何参与 UNIQUE 约束的值一样,每个列只允许一个 null 值。 UNIQUE 约束可以被 FOREIGN KEY 约束引用。

将 UNIQUE 约束添加到表中的现有列或列时,数据库引擎会检查列中的现有数据,以确保所有值都是唯一的。 如果将 UNIQUE 约束添加到具有重复值的列,数据库引擎将返回错误,并且不添加约束。

数据库引擎会自动创建 UNIQUE 索引,以强制实施 UNIQUE 约束的唯一性要求。 因此,如果尝试插入重复行,数据库引擎将返回一条错误消息,指出 UNIQUE 约束已被违反,并且不会将该行添加到表中。 除非显式指定聚集索引,否则默认创建唯一的非聚集索引以强制实施 UNIQUE 约束。

CHECK 约束

CHECK 约束通过限制一个或多个列接受的值来强制实施域完整性。 可以使用任何基于逻辑运算符返回 TRUE 或 FALSE 的逻辑(布尔值)表达式创建 CHECK 约束。 例如,可以通过创建一个 CHECK 约束来限制 工资 列的值范围,该约束仅允许从 $15,000 到 $100,000 的数据。 这可防止薪金超出常规薪金范围之外。 逻辑表达式将如下: salary >= 15000 AND salary <= 100000

可以将多个 CHECK 约束应用于单个列。 还可以通过在表级别创建单个 CHECK 约束,将单个 CHECK 约束应用于多个列。 例如,可以使用多列 CHECK 约束来确认任何country_region列值为USA的行在列中也有两个字符的值。 这使得在一个位置可以同时检查多个条件。

CHECK 约束类似于 FOREIGN KEY 约束,因为它们控制在列中放置的值。 区别在于它们如何确定哪些值有效:FOREIGN KEY 约束从另一个表中获取有效值的列表,而 CHECK 约束则确定逻辑表达式中的有效值。

谨慎

包含隐式或显式数据类型转换的约束可能会导致某些作失败。 例如,对作为分区切换源的表定义的此类约束可能会导致 ALTER TABLE...SWITCH 操作失败。 在约束定义中避免数据类型转换。

CHECK 约束的限制

CHECK 约束拒绝计算结果为 FALSE 的值。 由于 null 值计算为 UNKNOWN,它们在表达式中的存在可能会覆盖一个约束。 例如,假设您对intMyColumn施加一个约束,指定MyColumn只能包含值 10(MyColumn=10)。 如果将值 NULL 插入 到 MyColumn 中,数据库引擎将插入 NULL,并且不会返回错误。

如果所检查的条件对于表中的任何一行不是 FALSE,则 CHECK 约束将返回 TRUE。 CHECK 约束在行级别上运行。 如果刚刚创建的表没有任何行,则此表上的任何 CHECK 约束都被视为有效。 这种情况可能会产生意外结果,如下面的示例所示。

CREATE TABLE CheckTbl (col1 int, col2 int);  
GO  
CREATE FUNCTION CheckFnctn()  
RETURNS int  
AS   
BEGIN  
   DECLARE @retval int  
   SELECT @retval = COUNT(*) FROM CheckTbl  
   RETURN @retval  
END;  
GO  
ALTER TABLE CheckTbl  
ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 );  
GO  

添加的 CHECK 约束指定表 CheckTbl必须至少包含一行。 但是,由于表中没有可以检查此约束条件的行,因此 ALTER TABLE 语句可以成功执行。

在执行 DELETE 语句时,不会对 CHECK 约束进行验证。 因此,对具有某些类型的检查约束的表执行 DELETE 语句可能会产生意外的结果。 例如,假设对表 CheckTbl执行下列语句。

INSERT INTO CheckTbl VALUES (10, 10);  
GO  
DELETE CheckTbl WHERE col1 = 10;  

即使 DELETE 约束指定表 CHECK 必须至少包含 CheckTbl 行, 1 语句也会成功。

相关任务

注释

如果表已发布进行复制,则必须使用 Transact-SQL 语句 ALTER TABLE 或 SQL Server 管理对象(SMO)进行架构更改。 使用表设计器或数据库关系图设计器进行架构更改时,它会尝试删除并重新创建表。 无法删除已发布的对象,因此架构更改将失败。

任务 主题
介绍如何创建唯一约束。 创建唯一约束
介绍如何修改唯一约束。 修改唯一约束
介绍如何删除唯一约束。 删除唯一约束
介绍当复制代理在表中插入或更新数据时如何禁用 CHECK 约束。 对复制禁用 CHECK 约束
介绍在表中添加、更新或删除数据时如何禁用 CHECK 约束。 对 INSERT 和 UPDATE 语句禁用 CHECK 约束
介绍如何更改约束表达式或更改对特定条件启用或禁用约束的选项。 修改 CHECK 约束
介绍如何删除 CHECK 约束。 删除 CHECK 约束
介绍如何查看 CHECK 约束的属性。 唯一约束和 CHECK 约束