目录
1、约束类型
关键字 | 解释 |
---|---|
NOT NULL | 指示某列不能为空值 |
UNIQUE | 保证某列的每一行的值不重复 |
DEFAULT | 当没有给某个列赋值时的默认值 |
PRIMARY KEY | NOT NULL 和 UNIQUE 的结合,确保某列(或多列) 有唯一标识,称为主键 |
FOREIGN KEY | 保证一个表中的数据匹配另一个表中的值的参照完整性 |
CHECK | 保证列中的值符合指定的条件 (MySQL 5 不支持,不介绍) |
数据库的约束,其实是在方便程序猿,就拿 NOT NULL 来举例,指定某列中的每一行不能为 NULL,即也就标识了这个列的每一行必须存在数据,如果把这个作为一个君子间的约定,那就不靠谱,指定不那天某个程序猿忘了这个约定,果真搞了个空值,可能会给程序引发一些BUG,所以干脆把这种约定交给计算机来处理,一旦你没按照这个约定,就给你报错!
所以,约束就是让数据库帮助程序猿更好的检查数据是否正合理/正确!
2、NOT NULL
这个 NOT NULL,在创建表的时候,可以指定某列不为空,那么现在我们就来重新创建一张学生表:
create table student (
id int,
name varchar(10) not null,
sex varchar(1),
java float(5, 2),
python float(5, 2)
);
这里创建表的时候,直接在设置对应列的后面加上 not null,这个关键字即可。
如上代码意味着将来我要往 student 表中插入数据,name 这一列中每一行必须有数据,简单来说,就是每个学生不能没有姓名。
前面我们讲过可以指定列插入,也即不完全插入,那么现在就来测试一下:
insert into student(id, name) values(1, '张三');
-- Query OK, 1 row affected (0.01 sec)
这里显示插入成功,因为我们只是针对 name 这一列设置为 not null,所以不影响 java 和 python 字段,也即 id,java,python 这三个字段是允许不插入数据的,那么当我们插入数据时,不给 name 字段插入数据会怎么样呢?
insert into student(id, java) values(1, 97.2);
-- ERROR 1364 (HY000): Field 'name' doesn't have a default value
这里出现了 error,读这个报错信息,说 name 这个字段没有默认值,别忘了,在没有设默认值的时候,默认为 NULL,也就是在你新增的时候,必须给这个字段指定一个值。
那么问题来了,NULL 算值吗?既然你说这个字段没有默认值,那我放个 NULL 总可以了吧?看代码:
insert into student(id, name, java) values(1, null, 97.2);
-- ERROR 1048 (23000): Column 'name' cannot be null
那么通过这个报错,我们又能发现,name 字段不能为 null,即 null 是空值,也就是没有值的意思。所以在数据库中 null 不是值,是表示没有数据!
接下来我们去查看设置成 not null 之后,表结构上发生了哪些变化:
desc student;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(10) | NO | | NULL | |
| sex | varchar(1) | YES | | NULL | |
| java | float(5,2) | YES | | NULL | |
| python | float(5,2) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
-- 5 rows in set (0.00 sec)
看到这个表的结构,相信就水落石出了!我们最后在作一次总结:
总结:严格意义上来说,指定字段设置 not null,表明该字段不能为空,由于 Default(默认值)是 NULL,也就是在你没有给某个字段设置默认值的时候,你插入受 not null 限制的字段时,必须指定一个值。如果你指定了默认值,只要默认值不为 null,就可以使用默认值的值,简而言之,指定字段设置 not null,之后表明该字段不能为空!
3、UNIQUE
这个单词翻译过来就是唯一的,独一无二的,见名知意,给哪个字段加上这个约束,哪个字段的值就不能重复了,必须是唯一的!
接下来我们重新创建一个表,演示 unique 的作用以及一些细节问题:
-- 如果存在 student 表, 请先删除该表.
create table student (
id int unique,
name varchar(10),
sex varchar(1)
);
这次我们将学生的 id 设置是唯一的,那现在我们接下来就插入数据了:
insert into student values(1, '张三', '男');
-- Query OK, 1 row affected (0.01 sec)
insert into student values(1, '李四', '男');
-- ERROR 1062 (23000): Duplicate entry '1' for key 'id'
这里我们发现,插入第一条数据好好的没事,当插入第二条数据时报错了!阅读这个报错信息,它告诉我们,键 “id” 出现重复条目 “1”,相信看到这,你大概能知道 unique 的约束作用了。
那么 id 字段设置了 unique 约束,表的结构发生了哪些变化呢?
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| name | varchar(10) | YES | | NULL | |
| sex | varchar(1) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
-- 3 rows in set (0.00 sec)
明显看到 Key 不能重复了,这里有一个问题,我们没有把 id 字段设置 not null 约束,那么这个字段设置 unique 约束后可以出现两个空值吗?也即可以不设置任何值吗?
insert into student values(null, '李四', '男');
-- Query OK, 1 row affected (0.00 sec)
insert into student values(null, '王五', '男');
-- Query OK, 1 row affected (0.01 sec)
显而易见,允许这样做,这里再次验证了前面的说法,null 表示没有任何值,而 unique 是针对值重复,这个字段的值是唯一的,null 表示没有值,所以 unique 限制不了 null,这是很多小伙伴初学阶段容易犯错的细节点,你 get 到了吗?
数据库是如何判定当前这个数据是重复的呢?
先查找,再插入,所以在加上这个约束后,数据库的执行过程可能就变慢了,效率可能会受到影响,但是总比你手动检查要好上不少吧!
注意:unique 和 not null,可以一起使用,相当于主键约束(后面期),每一列可以有多个约束。
4、DEFAULT
这个约束是当字段中没有插入数据的时候默认的数据。
这里重新创建一张学生表,将 name 字段的默认值为:"无名氏":
create table student (
id int,
name varchar(10) default '无名氏',
sex varchar(1)
);
这样我们再来指定列插入一条数据:
insert into student(id, sex) values(1, '男');
-- Query OK, 1 row affected (0.00 sec)
select * from student;
+------+-----------+------+
| id | name | sex |
+------+-----------+------+
| 1 | 无名氏 | 男 |
+------+-----------+------+
-- 1 row in set (0.00 sec)
这里可以发现,在没有给 name 字段插入数据的时候,默认的数据就是设置的默认值 "无名氏"。
当然设置了 DEFAULT 不影响你手动指定数据,它只针对你没有指定数据时会给你插入一个你设定的默认值罢了!
这里可能有小伙伴好奇心重,于是想,我能不能手动把默认值设置为 null 呢?即空值呢?
create table student (
id int,
name varchar(10) default null,
sex varchar(1)
);
-- Query OK, 0 rows affected (0.03 sec)
可以是可以,但完全没必要啊!!! 这样做图个啥呢?
再进一步钻牛角尖,那我能在前面加上一个 not null 吗?这过分了啊!!!这不冲突才怪呢!
create table student (
id int,
name varchar(10) not null default null,
sex varchar(1)
);
-- ERROR 1067 (42000): Invalid default value for 'name'
后面这俩段代码,大家伙就当个乐子看了,没有研究的价值的!
下期预告:【MySQL】主键约束和外键约束