约束1:什么是约束

约束(Constraint)使用户可以定义数据库引擎执行数据完整性的方式,就是说,约束定义了有关列中允许的值的规则,强制数据表保持数据的完整性,表数据必须符合一定的条件。因为约束跟表数据有十分密切的关系,因此,通常在表定义中创建约束。事实上,表是数据库对象,约束也是一种特殊的数据库对象,只不过用于实现数据的完整性。在关系型数据库中,数据的完整性主要分为三类:

  • 实体完整性约束:数据是唯一的,相关的约束是主键约束(Primary Key),唯一约束(Unique);
  • 域完整性:数据值符合标准,相关的约束是:Check约束,默认值约束(Default),非空约束(NOT NULL);
  • 引用完整性:引用的数据必须存在或联动更新,相关的约束是:外键约束(Foreign Key

 综上所述,共有六种类型的约束,约束类型分别是:

  • Check约束:C = CHECK constraint
  • 默认值约束:D = DEFAULT constraint 
  • 外键约束:F = FOREIGN KEY constraint
  • 主键约束:PK = PRIMARY KEY constraint
  • 唯一约束:UQ = UNIQUE constraint
  • 非空约束:NOT NULL

除非空约束之外,每一个约束都是一个数据库对象,有名称,存在于sys.objects中,而非空约束比较特殊,不是一个数据库对象,没有名称,一般可以把非空属性作为列的属性,不把NOT NULL/NULL作为约束看待。

一,约束是数据库对象

由于约束是数据库对象,所有的约束都处于特定的数据库架构(internal)中,因此,处于同一个schema下的约束的名称不能重复,每一个约束的名称必须是唯一的。

通常情况下,约束的schema是其父对象(表)的架构。

1,约束不能同名

例如,在两个表中创建两个同名的约束:

create table dbo.dt_test
(
    id int identity not null constraint PK_ID primary key,
)
create table dbo.dt_test_add
(
    id int identity not null constraint PK_ID check(id>0),
)

当创建第二个约束时,SQL Server引擎抛出错误消息:

There is already an object named 'PK_ID' in the database. Could not create constraint. See previous errors.

2,查看约束对象 

通过sys.objects 查看约束对象的信息,每一个约束对象都必须依附在表对象上,称作约束的父对象。

select name as constraint_name
    ,object_id as constraint_id
    ,schema_name(schema_id) as schema_name
    ,object_name(parent_object_id) as parent_object_name
    ,type_desc as constraint_type
from sys.objects
where type in('C','D','F','PK','UQ')

三,特殊的列属性

跟约束有关的两个列属性是 Identity和 nullability,当使用select into命令创建数据表的一个副本时,数据列的名称和数据类型都会复制过去,同时 Identity和 nullability也会复制过去,但是其他5个约束对象的属性不会复制到新表中。这也是为什么不把非空约束(NOT NULL)作为约束来看待的原因。

四,约束的默认行为

主键约束(Primary key)和唯一约束(unique)都具有唯一性,实际上两者都会创建一个唯一索引,通过唯一索引来保证唯一性。这两个约束的不同点是:

  • 主键约束列必须都是非空的,而唯一索引列允许存在NULL值,但是,唯一索引中的NULL值是相同的;
  • 在一个表中只能创建一个主键约束,可以创建多个唯一约束;

五,应用约束的顺序

一般情况下,SQL Server引擎按照如下顺序应用约束:

  1. 默认值约束,如果字段没有显式赋值,应用defaut约束,为字段赋值;
  2. 非空约束,检查字段的值是否not null;
  3. check约束,检查字段的值是否满足check约束;
  4. 外键约束:检查字段是否存在外键;
  5. 唯一性约束:最后,检查字段的值是否满足唯一约束(unique)和主键约束;

六,约束的检查

通过ALTER TABLE命令,可以禁用或启用约束,也可以不检查现有数据。

1,对于已经存在的数据

在向一个表中新添加约束(CHECK约束或外键约束)之后,要检查表中已经存在的数据是否满足约束,可以使用WITH CHECK 选项,该选项用于对表中现存的数据进行约束的检查;而WITH NOCHECK 选项,是指对表中现存的数据不进行约束的检查,因为现存的数据可能不满足新建的约束,因此,建议使用WITH CHECK 选项。

2,对于新增加的数据

约束对于新增加的数据,都会做检查该数据是否满足约束。

ALTER TABLE  schema_name . table_name 
[ WITH { CHECK | NOCHECK } ] 
{ CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [ ,...n ] }

3,约束的启用或禁用

选项:{ CHECK | NOCHECK } CONSTRAINT ,用于启用或禁用指定的约束(CHECK约束或外键约束),当NOCHECK选项指定之后,后续的INSERT或UPDATE操作不会做CHECK和外键约束的检查。

默认值(DEFAULT)、主键(PRIMARY KEY)和唯一(UNIQUE)约束不能被禁用。

参考文档:

Constraints

ALTER TABLE (Transact-SQL)

原文地址:https://www.cnblogs.com/ljhdo/p/4539172.html