数据库的完整性是指数据的正确性、有效性和相容性。

例如,在性别字段中,只能取“男”或“女”两个值中的一个,没有第三个可取值;学生的学号必须唯一。在SQL Server中,系统提供了多种强制数据完整性的机制,以确保数据库中的数据质量。

完整性约束作用的对象

关系:包括若干元组间、关系集合上以及关系之间的联系的约束。

元组:包括元组中各个字段间联系的约束。

列:包括列的类型、取值范围、精度、唯一性、为空性、默认定义、CHECK约束、主键约束、外键约束。

完整性约束类型

实体完整性。

域完整性。

参照完整性。

用户定义完整性。

实体完整性

实体完整性将行定义为特定表的唯一实体。实体完整性作用的对象是列,强制表的标识符列或主键的完整性(通过UNIQUE约束、PRIMARY KEY约束或IDENTITY属性约束)。

域完整性作用的对象是列,是指给定列的输入有效性。强制域有效性的方法有:限制类型(通过数据类型)、格式(通过CHECK约束和规则)或可能值的范围(通过FOREIGN KEY约束、CHECK约束、DEFAULT定义、NOT NULL定义和规则)。

参照完整性

参照完整性作用的对象是关系。在输人或删除记录时,参照完整性保持表之间已定义的关系。在SQL Server中,引用完整性基于子表外键与主表主键之间或子表外键与主表唯一键之间的关系(通过FOREIGN KEY和CHECK约束)。参照完整性确保键值在所有表中一致。这样的一致性要求不能引用不存在的值,如果键值更改了,那么在整个数据库中,对该键值的所有引用要进行一致的更改。

用户定义完整性

用户定义完整性使用户可以定义不属于其他任何完整性分类的特定业务规则,作用的对象可以是列,也可以是元组或关系。所有的完整性类型都支持用户定义完整性,如CREATE TABLE中的所有列级和表级约束、存储过程和触发器。

CHECK约束

CHECK约束通过限制输入到列中的值来强制域的完整性。CHECK约束根据逻辑表达式返回的结果是TRUE还是FALSE来判断。例如,通过创建CHECK约束可将本科生的Age列的取值范围限制在14~40岁之间,从而防止输入的年龄超出正常的本科生范围。

(1)创建和修改CHECK约束

作为表定义的一部分在创建表时创建。

添加到现有表中。表和列可以包含多个CHECK约束。

修改或删除现有的CHECK约束。例如,可以修改表中列的CHECK约束的表达式。

(2)CHECK约束的设置

在现有表中添加CHECK约束时,该约束可以仅作用于新数据也可以同时作用于现有的数据。默认设置为CHECK约束同时作用于现有数据和新数据。

(3)禁用CHECK约束

下列情况可以禁用现有CHECK约束:

INSERT和UPDATE语句,可以允许不经约束确认修改表中的数据。在执行INSERT和UPDATE语句时,如果新数据违反约束或约束应只适用于数据库中已有的数据,那么可禁用CHECK约束。

复制处理。如果该约束为源数据库所特有,则在复制时应禁用CHECK约束。

默认值(Default)是指当用户向表中插人数据时,如果某些列未明确给出插入值,那么SQL Server将用预先在这些列上定义的值作为插入值。当某个默认值被创建后,有一个唯一的名字,并且成为数据库中的一个对象。用户要使用默认值时,需要把默认值对象绑定至表中相应的一列或多列上或某个用户定义的数据类型上。不使用时再将绑定解除。

实体完整性约束

1.交互式创建PRIMARY KEY约束。

启动SQL Server Management Studio,展开数据库中的“表”节点,右击表Student,选择“修改”选项,打开表设计器。

选择列Sno,单击工具栏中的“🔑”按钮,设置主键。在列最左侧的行选择器中显示一把钥匙。保存对表的修改后关闭表设计器。

2.交互式创建表,并创建PRIMARY KEY 约束。

右击数据库中的“表”节点,选择“新建表”,打开表设计器。输入表TEST_SC各列的设置。此时SNO和CNO列都是允许空值。选中SNO和CNO列,设为主键,此时变为不允许空值。(SNO,CNO)是关系TEST_SC的主键。保存修改,输入表名TEST_SC。

3.用create table语句创建表,并以列约束形式创建PRIMARY KEY 约束。

use jiaoxuedb
create table TEST_C(
  CNO char(2) constraint PK_TEST_C_CNO primary key,
  CN char(10),
  CT tinyint)

  展开表TEST_C的列和索引,查看各列的定义以及聚集类型的索引PK_TEST_C_CNO。

4.用create table创建表,并以表约束形式创建PRIMARY KEY约束。

create table TEST_TC(
  TNO char(2),
  CNO char(2),
  constraint PK_TEST_TC primary key (TNO, CNO))

  展开表TEST_TC的列和索引,查看各列的定义以及聚集类型的索引PK_TEST_TC。

5.用alter table语句为现有表创建PRIMARY KEY约束。

alter table Teacher
  add constraint PK_T primary key (Tno)

  在资源管理器中展开表Teacher的索引,可以看到增加了聚集类型的索引PK_T,Tno列成为主键。

6.交互式为现有表创建“UNIQUE约束”。

在资源管理器中右击表TEST_TC,选择“设计”选项,打开表设计器。单击工具栏中的“管理索引和键”按钮,打开“索引/键”对话框。

点击“添加”按钮,创建索引IX_TEST_TC,将名称修改为IX_TEST_TC1,将类型修改为唯一键,列选择TNO和CNO。关闭窗口后保存修改。

7.用alter table语句为现有表创建“UNIQUE约束”。

alter table Course
  add constraint UNIQUE_Cno unique (Cno)

  展开表Course的列和索引,查看各列的定义以及非聚集类型的索引UNIQUE_C。

8.交互式为现有表增加新列ID_SC,并设置此列属性为IDENTITY。

在资源管理器中右击表TEST_SC,选择“设计”选项,打开表设计器。输入新的一列,列名为ID_SC,数据类型为int,不允许空值。在下面列属性窗口中展开“标识规范”行,设置"(是标识)"为是,标识增量和标识种子默认为1。保存修改。

9.用alter table语句为现有表增加新列ID_TC,并设置此列属性为IDENTITY。

alter table TEST_TC
  add ID_TC int identity(1,1)

10.交互式删除现有表的主键并取消ID_SC列的标识属性。

在资源管理器中右击表TEST_SC,选择“设计”选项,打开表设计器。

选中SNO和CNO列,点击工具栏中的🔑按钮,删除主键。

选择列ID_SC,在列属性窗口中展开“标识规范”行,设置"(是标识)"为否。保存修改。

11.用alter table语句删除表的UNIQUE约束。

alter table Course
  drop constraint UNIQUE_Cno

域完整性约束

1.交互式为现有表创建DEFAULT和CHECK约束。

在资源管理器中右击表Teacher,选择“设计”选项,打开表设计器。单击选择SEX列,然后在表设计器下面的“列属性”框中的“默认值或绑定”输人框中,输入'男'。

单击工具栏中的“管理CHECK约束”按钮,打开“CHECK约束”对话框。单击“添加”按钮,在“(名称)”输入框中把默认名改为CHECK_T,将“在创建或重新启用时检查现有数据”选项设置为“否”。单击“表达式”右端的“…”按钮,打开“CHECK约束表达式”对话框,输入表达式:

(PROF = '教授' and COMM = 4000) or (PROF = '副教授' and COMM = 2000) or (PROF = '讲师' and COMM = 1500) or (PROF = '助教' and COMM = 1000)

单击“确定”按钮,若约束表达式正确,则关闭表T的“CHECK约束表达式”对话框;若有错误,则修改表达式至正确,再单击“确定”按钮。关闭对话框,保存修改。

2.用alter table语句为现有表创建DEFAULT约束。

alter table Student
  add constraint DF_S_SEX default '男' for SEX

3.用alter table语句为现有表创建CHECK约束。

alter table Student with check
  add constraint CHECK_AGE check (AGE >= 14 and AGE <= 40)

  用表设计器打开表Student,管理CHECK约束,查看新建的约束。对话框显示了约束的表达式和对已有数据进行检查。

4.用create table语句创建表,包含DEFAULT和CHECK约束。

create table TEST_S(
  SNO char(2) not null,
  SN char(8) not null,
  SEX char(2) null
    constraint DEFAULT_S_SEX default '男'
    constraint CHECK_S_SEX check (SEX = '男' or SEX = '女'),
  AGE tinyint null
    constraint DEFAULT_S_AGE default 18
    constraint CHECK_S_AGE check (AGE >= 14 and AGE <= 40))

5.用alter table语句删除表的DEFAULT约束

alter table Teacher
  drop constraint DF_Teacher_SEX

6.用alter table语句删除表的CHECK约束。

alter table Teacher
  drop constraint CHECK_T

7.交互式删除表的DEFAULT约束及CHECK约束。

用表设计器打开表TEST_S,选择SEX列,删除默认值“男”。打开CHECK约束对话框,选中CHECK_S_AGE,点击“删除”按钮,完成交互式修改。

参照完整性约束

1.交互式创建表与表之间的参照关系。

用表设计器打开表SC,单击工具栏中的“关系”按钮,打开“外键关系”对话框。单击“添加”按钮,添加一个关系。

单击“表和列规范”右端的按钮,打开“表和列”对话框。主键表选择表Student,主键为字段SNO,外键表选择SC,外键为字段SNO,点击确定。

将“在创建或重新启用时检查现有数据”一项设置为“否”,展开“INSERT和UPDATE规范”,将“更新规则”一项设置为“级联”。关闭窗口,保存修改。

验证级联的更新规则:将表Student中的S1改为S6后,表SC中的S1也变成了S6。

2.用alter table语句创建表与表之间的参照关系。

alter table TC with nocheck
  add constraint FK_T_TC foreign key (TNO) references Teacher (TNO)
  on delete cascade

  执行语句后验证级联的删除规则:将主表T中的T1记录删除后,从表TC中的T1记录也被删除了。

3.创建数据库jiaoxuedb中5个表之间的关联关系图。

启动SQL Server Management Studio,在左窗格中展开数据库jiaoxuedb。右击“数据库关系图”,选择“新建数据库关系图”选项。打开2个窗口,一个是创建关系图的窗口;一个是“添加表”窗口,其中列出了jiaoxuedb中的所有用户表。

选择表Course,单击“添加"按钮,表Course即加入关系图窗口中。重复此过程,把表Student、SC、Teacher、TC都添加到关系图窗口中,添加完成后还可调整5个表的相对位置。

在关系图窗口中,可以看到表Teacher与TC之间已存在一条关系线。由于表Teacher与TC之间是一对多关系,所以关系线表示“多对象”的一端连接着表TC,表示“一个对象”的一端连接着表Teacher。同理,表Student与SC此前也已创建了一对多的关联关系,所以它们之间也存在一条一对多的关系线。

通过Cno创建表Course和TC之间的一对多关联关系。单击并按住表Course中的Cno字段,拖动至表TC中的Cno字段,松开鼠标左键,打开“外键关系”和“表和列”两个窗口,观察窗口中的各项值。

单击“表和列”窗口的“确定”按钮退出该窗口,然后在“外键关系"窗口中,将“在创建或重新启用时检查现有数据”一项设置为“否”,单击“INSERT和UPDATE规范”左侧的按钮,将“更新规则”和“删除规则”两项均设置为“层叠”。

单击“确定”按钮,关闭外键关系窗口,回到关系图窗口中,此时表Course与TC之间生成了一条一对多的关系线。

通过Cno创建表Course和SC之间的一对多关联关系。

单击工具栏中的存盘按钮,打开“另存为”对话框,在“输人关系图名称”框中输入S_SC_C_TC_T。单击“确定”按钮,回到关系图窗口。

查看数据库jiaoxuedb中关系图对象。在对象资源管理器中,依次展开“数据库”→jiaoxuedb→“数据库关系图”节点,右窗格中即显示出刚创建的S_SC_C_TC_T关系图。

4.交互式删除表和表之间的参照关系。

用表设计器打开表Course,单击工具栏中的“关系”按钮,打开表Course的外键关系窗口。

在“选定的关系”框中,选择名称为FK_TC_C的关系,单击“删除”按钮,此关系被删除。关闭外键关系窗口,保存修改。