3.2.4 约束管理
数据完整性指的是数据的一致性和正确性。完整性约束指数据库的内容必须随时遵守的规则。若定义了数据完整性约束,MySQL会负责数据的完整性,每次更新数据时,MySQL都会测试新的数据内容是否符合相关的完整性约束条件,只有符合完整性约束条件的更新才被接受。
MySQL中的约束保存在information_schema数据库的table_constraints表中,可以通过该表查询约束信息。约束主要完成对数据的检验,保证数据库数据的完整性;如果有相互依赖数据,保证该数据不被删除。
MySQL中常用六类约束:
not null:非空约束,指定某列值不为空。
unique:唯一约束,指定某列和几列组合的数据值不能重复。
primary key:主键约束,指定某列的数据值不能重复、唯一且不为null。
foreign key:外键,指定该列记录属于主表中某列的记录,参照另一条数据。
check:检查,指定一个表达式,用于检验指定数据。
default:默认约束,指定某列的默认值。
注意:目前MySQL版本不支持check约束,但可以使用check约束,而没有任何效果。
根据约束数据列限制,约束可分为:
单列约束:每个约束只约束一列。
多列约束:每个约束约束多列数据。
1.非空约束not null
非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统会报错。
null类型特征:所有的类型的值都可以是null,包括int、float、varchar等数据类型。注意:空字符串‘’是不等于null,0也不等于null。
非空约束的语法格式如下:
字段名 数据类型not nu l l
【例3.4】在bookDB数据库下创建bookType(图书类别)表,表结构见表3-1。要求:为bookType表的btname列添加非空约束。
SQL语句执行效果如下:
上面的bookType表加上了非空约束,可以用alter来修改或增加非空约束。
例如:
也可以取消非空约束。
例如:
2.唯一约束unique
唯一约束要求该列唯一,允许为空,但只能出现一个空值。唯一约束可以确保一列或者几列不出现重复值。
唯一约束的语法格式如下:
(1)在定义字段之后直接指定唯一约束
语法格式如下:
【例3.5】在bookDB数据库下创建bookType1表,表结构见表3-1。
要求:为bookType1表的btname列添加唯一约束。
SQL语句执行效果如下:
(2)在定义完所有列之后指定唯一约束
语法格式如下:
以下代码可以完成例3.5相同的功能,代码如下:
其中constraint是定义约束的关键字;uk_btname为该约束的名字(uk为唯一约束命名的前缀);unique(btname)为btname列指定唯一约束。
上面的bookType1表加上了唯一约束,也可以用alter来修改或增加唯一约束。
添加唯一约束:
例如:
3.主键约束primary key
主键约束相当于唯一约束与非空约束的组合,主键约束列不允许重复,也不允许出现空值;如果是多列组合的主键约束,那么这些列都不允许为空值,并且组合的值不允许重复。每个表最多只允许一个主键。主键约束可以在列级别创建,也可以在表级别上创建。
MySQL在创建主键约束时,系统默认在对应字段和字段组合上建立唯一索引(后面项目介绍索引)。主键能够唯一地标识表中的一条记录,主键和记录之间的关系如同身份证和人之间的关系,它们之间是一一对应的。主键分为两种类型:单字段主键和多字段联合主键。
(1)单字段主键
主键由一个字段组成,SQL语句格式分为以下两种情况。
①定义列的同时指定主键,语法格式如下:
【例3.6】在bookDB数据库下创建bookType2表,表结构见表3-1。要求:为bookType2表的btid列添加主键约束。
SQL语句执行效果如下:
②在定义完所有列之后指定主键,语法格式如下:
以下代码可以完成例3.6相同的功能,代码如下:
其中constraint是定义约束的关键字;pk_btid为该约束的名字(pk为主键约束命名的前缀);primary key(btid)为btid列指定主键约束。
(2)多字段联合主键
主键由多个字段联合组成,语法格式如下:
【例3.7】在bookDB数据库下创建bookInfo1表,表结构见表3-3。要求:为book Info1表的bid、bname列添加主键约束。
SQL语句执行效果如下:
上面的bookType2表加上了主键约束,也可以用alter来删除、增加或修改主键约束。
alter删除主键约束:
例如:
alter添加主键:
例如:
alter修改列为主键:
例如:
设置主键自增:
对于auto_increment自增模式,设置自增后,在插入数据的时候不需要给该列插入值。
4.外键约束foreign key
外键用来在两个表的数据之间建立链接,它可以是一列或者多列。一个表可以有一个或多个外键。外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一个外键值必须等于另一个表中主键列的某个值。
外键:首先它是表中的一个字段,它可以不是本表的主键,但对应另外一个表的主键或唯一约束。外键的主要作用是保证数据引用的完整性,定义外键后,不允许删除在另一个表中具有关联关系的行。例如:图书类别表bookType的主键是btid,在图书信息表book Info中有一个键btid与这个btid相关联。其中bookType表为主表,bookInfo表为从表。
主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的表即是主表。
从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的表即是从表。
创建外键的语法格式如下:
“外键名”为定义的外键约束的名称,一个表中不能有多个相同名称的外键;“字段名”表示子表需要添加外键约束的字段列;“主表名”即被子表外键所依赖的表的名称;“主键列”表示主表中定义的主键列,或者主键列组合。
【例3.8】在bookDB数据库下,删除已经创建过的bookType、book Info及相关表。重新创建bookType、bookInfo表,表结构见表3-9、表3-10,这两个表中的bookInfo表中的btid列引用了bookType表中的btid列中的值,其中bookType表为主表,book Info表为从表。
表3-9 bookType表结构及约束要求
表3-10 book Info表结构及约束要求
删除可能已经存在的表bookType、bookInfo:
在以上代码外键约束的定义中,constraint fk_btid是可以省略的,如果省略外键约束的名称,系统会默认给外键约束分配名称。
注意,外键约束的外键列,在主表中引用的只能是主键或唯一键约束的列,假定引用的主表列不是唯一的记录,那么从表引用的数据就不确定记录的位置。通常先建主表,然后再建从表,这样从表参照引用的主表才存在。主表中被引用的列与从表中外键列的数据类型必须一致。
上面对bookInfo表加上了外键约束,也可以用alter来增加、删除外键约束。
•增加外键约束
例如:
•删除外键约束
例如:
•外键绑定关系
例如:
这里使用了“on delete cascade”“on update cascade”,意思是如果主表中被引用的列(主键列/唯一列)对应数据被删除或者更新时,将关联从表中的数据完全删除或者相应地更新。
5.检查约束check
MySQL可以使用check约束,但check约束对数据验证没有任何作用。
上面check约束要求bprice必须在0~200,但没有任何作用。但在创建table的时候,没有任何错误或警告。
6.默认约束default
默认约束指定某列的默认值。如因为计算机类的图书比较多,所以bookInfo表中的btid列就可以设置默认值为“1001”。如果插入一条新的记录时没有为这个字段赋值,那么系统会自动为这个字段赋值为“1001”。
默认约束的语法格式如下:
例如:
以上语句执行成功后,表book Info上的btid字段就拥有了一个默认值1001,新插入的记录如果没有指定部门编号,则默认都为1001。