文章目录
一、简介
实体完整性(Entity Integrity) :例如同一个表中,不能存在两条完全相同无法区分的记录域完整性(Domain Integrity) :例如年龄范围0-120,性别范围“男/女”引用完整性(Referential Integrity) :例如员工所在部门,在部门表中要能找到这个部门用户自定义完整性(User-defined Integrity) :例如用户名唯一、密码不能为空等,本部门经理的工资不得高于本部门职工的平均工资的5倍。
SELECT * FROM information_schema.table_constraints
WHERE table_name = '表名称';
二、外键约束
2.1 说明

- 主表(父表):被引用的表,被参考的表
- 从表(子表):引用别人的表,参考别人的表
- 从表的外键列,必须引用/参考主表的
主键或唯一约束的列 - 当主表的记录被从表参照时,主表如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据
- 从表的外键列与主表被参照的列名字可以不相同,但是
数据类型必须一样,逻辑意义一致 - 当创建外键约束时,系统默认会在所在的列上建立对应的普通索引
- 删除外键约束后,必须
手动删除对应的索引
2.2 使用外键
- 建表时
create table 主表名称(
字段1 数据类型 primary key,
字段2 数据类型
);
create table 从表名称(
字段1 数据类型 primary key,
字段2 数据类型,
[CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
);
create table dept(
did int primary key,
dname varchar(50)
);
create table emp(
eid int primary key,
ename varchar(5),
deptid int,
foreign key (deptid) references dept(did)
);
- 建表后
ALTER TABLE 从表名 ADD [CONSTRAINT 约束名] FOREIGN KEY (从表的字段)
REFERENCES 主表名(被引用字段) [on update xx][on delete xx];
ALTER TABLE emp1 ADD [CONSTRAINT emp_dept_id_fk]
FOREIGN KEY(dept_id) REFERENCES dept(dept_id);
约束关系是针对双方的- 添加了外键约束后,主表的修改和删除数据受约束
- 添加了外键约束后,从表的添加和修改数据受约束
- 删除主表时,要求从表从表先删除,或将从表中外键引用该主表的关系先删除
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';
ALTER TABLE 从表名 DROP FOREIGN KEY 外键约束名;
SHOW INDEX FROM 表名称;
ALTER TABLE 从表名 DROP INDEX 索引名;
2.3 约束等级
| 约束等级 | 说明 |
|---|
| Cascade | 在父表上update/delete记录时,同步update/delete掉子表的匹配记录 |
| Set null | 在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null |
| No action | 如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作 |
| Restrict | 同no action,都是立即检查外键约束 |
| Set default | 父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别(在可视化工具SQLyog中可能显示空白) |
三、其它约束
3.1 非空约束
CREATE TABLE 表名称(
字段名 数据类型,
字段名 数据类型 NOT NULL,
字段名 数据类型 NOT NULL
);
alter table 表名称 modify 字段名 数据类型 not null;
ALTER TABLE emp MODIFY sex VARCHAR(30) NOT NULL;
alter table 表名称 modify 字段名 数据类型;
ALTER TABLE emp MODIFY sex VARCHAR(30);
3.2 唯一性约束
- 建表时
CREATE TABLE 表名称(
字段名 数据类型,
字段名 数据类型 UNIQUE,
字段名 数据类型
);
CREATE TABLE 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
UNIQUE KEY `key_name` (`field_list`])
);
- 建表后
alter table 表名称 modify 字段名 字段类型 unique;
alter table 表名称 add unique key(字段列表);
ALTER TABLE USER
DROP INDEX unique_key_name;
3.3 主键约束
- 建表时
create table 表名称(
字段名 数据类型 primary key,
字段名 数据类型,
字段名 数据类型
);
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
[constraint 约束名] primary key(字段列表)
);
- 建表后
ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表);
alter table 表名称 drop primary key;
3.4 自增约束
- 一个表最多只能有一个自增长列
- 自增长列约束的列必须是键列(主键列,唯一键列)
- 自增约束的列的数据类型必须是整数类型
- 如果自增列指定了 0 和 null,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值。
- 建表前
create table 表名称(
字段名 数据类型 primary key auto_increment,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
create table 表名称(
字段名 数据类型 default 默认值 ,
字段名 数据类型 unique key auto_increment,
字段名 数据类型 not null default 默认值,,
primary key(字段名)
);
- 建表后
alter table 表名称 modify 字段名 数据类型 auto_increment;
alter table 表名称 modify 字段名 数据类型;
3.5 检查约束
mysql> CREATE TABLE employee(
-> eid INT PRIMARY KEY,
-> ename VARCHAR(20),
-> gender VARCHAR(20) CHECK(gender IN ('male', 'female')),
-> age TINYINT CHECK(0 <= age <= 150)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> SHOW CREATE TABLE employee\G
*************************** 1. row ***************************
Table: employee
Create Table: CREATE TABLE `employee` (
`eid` int NOT NULL,
`ename` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`gender` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`age` tinyint DEFAULT NULL,
PRIMARY KEY (`eid`),
CONSTRAINT `employee_chk_1` CHECK ((`gender` in (_latin1'male',_latin1'female'))),
CONSTRAINT `employee_chk_2` CHECK (((0 <= `age`) <= 150))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)
mysql> INSERT INTO employee VALUES (1, 'rayslee', 'male', 100), (2, 'monica', 'female', 18);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> INSERT INTO employee VALUES (1, 'joshua', 'secret', 200);
ERROR 1264 (22003): Out of range value for column 'age' at row 1
mysql> INSERT INTO employee VALUES (1, 'joshua', 'secret', 100);
ERROR 3819 (HY000): Check constraint 'employee_chk_1' is violated.
mysql>
3.6 默认值
- 建表时
create table 表名称(
字段名 数据类型 primary key,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
- 建表后
alter table 表名称 modify 字段名 数据类型 default 默认值;
alter table 表名称 modify 字段名 数据类型 default 默认值 not null;
alter table 表名称 modify 字段名 数据类型 ;
alter table 表名称 modify 字段名 数据类型 not null;