文章目录
数据库的约束就是关系型数据库给我们提供的一种"校验数据"合法性的机制
创建表时,可以指定某列不为空
- create table student(
- id int not null,
- sn int,
- name varchar(20),
- qq_mail varchar(20)
- );
-
- mysql> desc student;
- +---------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-------------+------+-----+---------+-------+
- | id | int(11) | NO | | NULL | |
- | sn | int(11) | YES | | NULL | |
- | name | varchar(20) | YES | | NULL | |
- | qq_mail | varchar(20) | YES | | NULL | |
- +---------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
保证某列的每行必须有唯一的值
重新设置一下表的结构
- create table student1(
- id int not null,
- sn int unique,
- name varchar(20),
- qq_mail varchar(20)
- );
-
- mysql> desc student1;
- +---------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-------------+------+-----+---------+-------+
- | id | int(11) | NO | | NULL | |
- | sn | int(11) | YES | UNI | NULL | |
- | name | varchar(20) | YES | | NULL | |
- | qq_mail | varchar(20) | YES | | NULL | |
- +---------+-------------+------+-----+---------+-------+
表示sn这列的值时唯一的不重复的
规定没有给列赋值时的默认值
指定插入数据时,name列为空,默认值unkown
- create table student2(
- id int not null,
- sn int unique,
- name varchar(20) default 'unkown',
- qq_mail varchar(20)
- );
-
- mysql> desc student2;
- +---------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-------------+------+-----+---------+-------+
- | id | int(11) | NO | | NULL | |
- | sn | int(11) | YES | UNI | NULL | |
- | name | varchar(20) | YES | | unkown | |
- | qq_mail | varchar(20) | YES | | NULL | |
- +---------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
插入一个id但不插入name时:
- insert into student2 (id) values (1);
-
- mysql> select*from student2;
- +----+------+--------+---------+
- | id | sn | name | qq_mail |
- +----+------+--------+---------+
- | 1 | NULL | unkown | NULL |
- +----+------+--------+---------+
- 1 row in set (0.00 sec)
name是默认值
NOT NULL 和 UNIQUE 的结合
确保某列有唯一标识,有助于快速找到表中的一个特定记录
- create table student3(
- id int not null primary key,
- sn int unique,
- name varchar(20) default 'unkown',
- qq_mail varchar(20)
- );
-
- mysql> desc student3;
- +---------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-------------+------+-----+---------+-------+
- | id | int(11) | NO | PRI | NULL | |
- | sn | int(11) | YES | UNI | NULL | |
- | name | varchar(20) | YES | | unkown | |
- | qq_mail | varchar(20) | YES | | NULL | |
- +---------+-------------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
主键是not null 和 unique 的结合,也可以不用 not null
id int primary key
对于整数类型的主键,例如id,常搭配自增长auto_increment来使用
当插入数据对应字段不给定值时,使用最大值加一
- mysql> create table student4(
- id int primary key auto_increment,
- sn int unique,
- name varchar(20) default 'unkown',
- qq_mail varchar(20)
- );
接下来我们插入记录时,id为null
- mysql> insert into student4 values (null,1000,'zhangsan',null);
- Query OK, 1 row affected (0.00 sec)
-
- mysql> insert into student4 values (null,1001,'zhangsi',null);
- Query OK, 1 row affected (0.00 sec)
-
- //将id置为100
- insert into student4 values(100,1002,'zhangwu',null);
- //将id置为null
- insert into student4 values(null,1003,'zhangliu',null);
-
-
- 结果
- mysql> select *from student4;
- +-----+------+----------+---------+
- | id | sn | name | qq_mail |
- +-----+------+----------+---------+
- | 1 | 1000 | zhangsan | NULL |
- | 2 | 1001 | zhangsi | NULL |
- | 100 | 1002 | zhangwu | NULL |
- | 101 | 1003 | zhangliu | NULL |
- +-----+------+----------+---------+
- 4 rows in set (0.00 sec)
可以看出,使用自增长之后,插入数据给值时,用给定的值插入,插入数据不给值时,默认插入最近一次的最大值+1
保证一个表中的数据匹配另一个表中的值的参照完整性
创建一个班级表class,id为主键.
创建学生表student,一个学生对应一个班级,一个班级对应多个学生。使用id为主键, classes_id为外键,关联班级表id
- create table class(
- id int primary key,
- name varchar(20),
- `desc` VARCHAR(100)
- );
- Query OK, 0 rows affected (0.03 sec)
-
- mysql> desc class;
- +-------+--------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+--------------+------+-----+---------+-------+
- | id | int(11) | NO | PRI | NULL | |
- | name | varchar(20) | YES | | NULL | |
- | desc | varchar(100) | YES | | NULL | |
- +-------+--------------+------+-----+---------+-------+
- 3 rows in set (0.00 sec)
- create table student5(
- id int primary key auto_increment,
- sn int unique,name varchar(20) default 'unknow',
- qq_mail varchar(20),
- class_id int,
- foreign key(class_id) references class(id)
- );
- Query OK, 0 rows affected (0.03 sec)
-
- mysql> desc student5;
- +----------+-------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+-------------+------+-----+---------+----------------+
- | id | int(11) | NO | PRI | NULL | auto_increment |
- | sn | int(11) | YES | UNI | NULL | |
- | name | varchar(20) | YES | | unknow | |
- | qq_mail | varchar(20) | YES | | NULL | |
- | class_id | int(11) | YES | MUL | NULL | |
- +----------+-------------+------+-----+---------+----------------+
- 5 rows in set (0.00 sec)
此时学生表就和班级表关联起来了
外键约束是两个表之间的相互约束

我们插入一个非法数据,现在class的id列还是空的,插任何数据都会不合法
- insert into student5 values(1,1001,'张三',null,10);
-
-
- ERROR 1452 (23000): Cannot add or update a child row:
- a foreign key constraint fails (`java_3`.`student5`,
- CONSTRAINT `student5_ibfk_1` FOREIGN KEY (`class_id`)
- REFERENCES `class` (`id`))
插入失败,因为class的id列没有10这个数据
说明学生表中的数据依赖于班级表的数据,班级表的数据对学生表的数据产生约束力,班级表为父表,学生表为子表
我们先给班级表和学生表插入数据
- mysql> insert into class values(1,'java001',null);
- Query OK, 1 row affected (0.00 sec)
-
- mysql> insert into student5 values(1,1001,'张三',null,1);
- Query OK, 1 row affected (0.00 sec)
-
- mysql> select*from class;
- +----+---------+------+
- | id | name | desc |
- +----+---------+------+
- | 1 | java001 | NULL |
- +----+---------+------+
- 1 row in set (0.00 sec)
-
- mysql> select*from student5;
- +----+------+------+---------+----------+
- | id | sn | name | qq_mail | class_id |
- +----+------+------+---------+----------+
- | 1 | 1001 | 张三 | NULL | 1 |
- +----+------+------+---------+----------+
- 1 row in set (0.00 sec)
因为数据都是合法的,所以成功插入
下面举例说明子表也会反过来约束父表
- mysql> delete from class where id = 1;
- ERROR 1451 (23000):
- Cannot delete or update a parent row:
- a foreign key constraint fails (`java_3`.`student5`,
- CONSTRAINT `student5_ibfk_1` FOREIGN KEY (`class_id`)
- REFERENCES `class` (`id`))
当我们删除班级表中的数据时,发现删除失败
原因是班级表的数据被学生表给引用了,如果删除成功,那么子表的数据就没有意义了
因此父表的数据被引用时,是不能删除的,如果要删除,就先删除子表后删除父表