为什么需要约束
数据完整性(Data Integrity)是指数据的精确性(Accuracy) 和可靠性(Reliability)。 它是防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的。
为了保证数据的完整性,SQL规范以约束的方式对表数据进行额外的条件限制。从以下四个方面考虑:
●实体完整性(Entity Integrity).例如,同一个表中,不能存在两条完全相同无法区分的记录
●域完整性(Domain Integrity):例如:年龄范围0-120,性别范围“男/女”
●引用完整性(Referential Integrity):例如:员工所在部门,在部门表中要能找到这个部门
●用户自定义完整性(User-defined Integrity) :例如:用户名唯一、密码不能为空等 ,本部]经理的工资不得高于本部门职工的平均工资的5倍。
什么是约束
约束是表级的强制规定。
可以在创建表时规定约束,或者在表创建之后通过ALTER TABLE语句添加或删除约束。
按约束作用分类:
非空约束,唯一性约束,主键约束,外键约束,检查约束,默认值约束
按约束作用范围分类
列级约束:将此约束声明在对应字段的后面
表级约束:在表中所有字段声明完,在所有字段的后面声明约束
列级约束:主键,外键,唯一,检查,默认,非空
表级约束:主键,外键,唯一,检查
非空约束
作用
限定某个字段/某列的值不能为空
关键字
NOT NULL
在创建表时添加约束:
CREATE TABLE test1(
id INT NOT NULL,
salary DECIMAL(10,2),
email VARCHAR(20),
last_name VARCHAR(20) NOT NULL
)
在ALTER TABLE时添加约束
ALTER TABLE test1
MODIFY email VARCHAR(20) NOT NULL;
在ALTER TABLE时删除约束
ALTER TABLE test1
MODIFY email VARCHAR(20) NULL;
特点
●一个表可以有很多个列分别限定了非空
●0不等于NULL,空字符串也不等于NULL
唯一性约束
作用
用来限制某个字段/某列的值不能重复。
关键字
UNIQUE
在创建表时添加约束:
CREATE TABLE test2(
id INT UNIQUE,#列级约束
salary DECIMAL(10,2),
email VARCHAR(20),
last_name VARCHAR(20),
#表级约束
CONSTRAINT uk_test2_email UNIQUE(email)
);
复合的唯一性约束
CREATE TABLE test2(
id INT UNIQUE,#列级约束
salary DECIMAL(10,2),
email VARCHAR(20),
last_name VARCHAR(20),
#表级约束
CONSTRAINT uk_test2_email_sal UNIQUE(email,salary)
);
在ALTER TABLE时添加约束
ALTER TABLE 表名
ADD CONSTRAINT 约束名 UNIQUE(列名)
ALTER TABLE 表名
MODIFY 列名 数值类型 UNIQUE
ALTER TABLE test2
ADD CONSTRAINT uk_test2_sal UNIQUE(salary)
ALTER TABLE test2
MODIFY last_name VARCHAR(20) UNIQUE
特点
●同一个表可以有多个唯一约束
●唯一性约束允许列值为空,并且允许存在多个NULL值
●在创建唯一性约束时,如果不给唯一性约束命名,就默认和列名相同
●创建复合的唯一性约束时,在INSERT时,如果两组数据至少有一个不一样,则可以成功添加
删除唯一性约束
●添加唯一性约束的列上也会自动创建唯一索引。
●删除唯一约束只能通过删除唯一索引的方式删除。
●删除时需要指定唯一索引名,唯一索引名就和唯一约束名一样
●如果创建唯一约束时未指定名称,如果是单列,就默认和列名相同:如果是组合列,那么默认和添加约束时()中第一个列名相同。
ALTER TABLE test2
DROP INDEX id
主键约束
作用
用来唯一标识表中的一行记录
关键字
PRIMARY KEY
在创建表时添加约束:
CREATE TABLE test3(
id INT PRIMARY KEY,
email VARCHAR(20),
last_name VARCHAR(20),
salary DECIMAL(10,2)
)
CREATE TABLE test3(
id INT,
email VARCHAR(20),
last_name VARCHAR(20),
salary DECIMAL(10,2)
CONSTRAINT PRIMARY KEY(id)
)
特点
●主键约束相当于唯一性约束+非空约束的组合
●一个表最多可以有一个主键约束
●主键约束可以对应一列或多列(复合主键),而且这些列不可以存在NULL,组合的值不可以重复
●MySQL的主键名总为PRIMARY,无法自己命名
●当创建主键约束时,系统默认会在所在的列或者列组合上建立对应的主键索引
自增列:AUTO_INCREMENT
作用
某个字段的自增
关键字
auto_increment
在创建表时添加约束:
CREATE TABLE test3(
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(20),
last_name VARCHAR(20),
salary DECIMAL(10,2)
)
在ALTER TABLE时添加约束
ALTER TABLE test3
MODIFY id INT AUTO_INCREMENT
特点和要求
●一个表最多有一个自增长列
●自增约束的列必须是整数类型
●自增长列约束的列必须是键列(主键列,唯一键列)
●如果自增列指定了0和NULL(insert),会在当前最大值的基础上自增,如果手动设置了具体值(insert),则直接赋为具体值。在实际开发中,不用给对应字段赋值。
删除约束
ALTER TABLE 表名
MODIFY 列名 数值类型
ALTER TABLE test3
MODIFY id INT
外键约束
作用
限制某个表的某个字段的引用完整性
关键字
FOREIGN KEY
在创建表时添加约束:
先创建主表:
CREATE TABLE dept(
dept_id int,
dept_name varchar(20)
)
ALTER TABLE dept
MODIFY dept_id int PRIMARY KEY
在创建从表:
create table empl(
emp_id int PRIMARY KEY AUTO_INCREMENT,
emp_name varchar(20),
dept_id int,
CONSTRAINT fk_dept_id FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
)
主表和从表/父表和子表
表(父表) :被引用的表,被参考的表
从表(子表) :引用别人的表,参考别人的表
例如:员工表的员工所在部门这个字段的值要参考部门表:部门表是主表,员工表是从表。
学生表、课程表、选课表:选课表的学生和课程要分别参考学生表和课程表,学生表和课程表是主表,选课表是从表。
特点
●向从表中添加数据时,外键列对应的值必须在主表中存在
●从表的外键列,必须引用/参考主表的主键或唯一约束的列
因为被依赖/被参考的值必须是唯一的
●在创建外键约束时,如果不给外键约束命名,默认名不是列名,而是自动产生一个外键名(例如
student_ ibfk_1;),也可以指定外键约束名。
●创建(CREATE)表时就指定外键约束的话,先创建主表,再创建从表
●删表时,先删从表(或先删余外键约束) ,再删除主表
●当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据
●在“从表”中指定外键约束,并且一个表可以建立多个外键约束
●从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。
●当创建外键约束时,系统默认会在所在的列上建立对应的普通索引。如果设置外键时没有起名,索引名就是列名。
●删除外键约束后,必须手动删除对应的索引
约束等级
●Cascade方式: 在父表上update/delete记录时,同步update/delete掉子 表的匹配记录
●Set null方式: 在父表上update/delete记录时, 将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null
●No action方式: 如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
●Restrict方式:同no action, 都是立即检查外键约束
对于外键约束,最好是采用: ON UPDATE CASCADE ON DELETE RESTRICT 的方式。
ON UPDATE CASCADE ON DELETE RESTRICT:在对主表update时采用Cascade方式,delete时采用Restrict方式
CREATE TABLE dept(
dept_id int PRIMARY KEY,
dept_name varchar(20)
)
create table empl(
emp_id int PRIMARY KEY AUTO_INCREMENT,
emp_name varchar(20),
dept_id int,
CONSTRAINT fk_empl_dept_id FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
ON UPDATE CASCADE ON DELETE RESTRICT
)
删除外键约束
先删除外键约束
ALTER TABLE empl
DROP FOREIGN kEY fk_empl_dept_id
再删除外键约束对应的普通索引
ALTER table empl
DROP index fk_empl_dept_id
检查约束
作用
检查某个字段的值是否符合符号XX要求,一般指的是值的范围
关键字
CHECK
在创建表时添加约束:
CREATE TABLE demo(
id int,
last_name VARCHAR(20),
salary int CHECK (salary>5000)
)
默认值约束
作用
给某个字段指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值
关键字
DEFAULT
在创建表时添加约束:
create table main(
id int,
last_name varchar(20),
salary DECIMAL(10,2) DEFAULT 5000
)
在ALTER TABLE时添加约束:
ALTER table main
modify salary DECIMAL(10,2) DEFAULT 5000