@TOC
写在前面
我们已经会创建数据表了,不过有时候会看到not null等字样,这些便是字段约束的内容,我们好好看一看什么是约束,又有哪些约束,这份博客时纯理论的,我们自己要理解这里面的内容
什么是字段约束
简而言之,字段约束就是将字段的内容定一个规则,我们要按照规则办事,常见的字段约束有下面几个
约束的分类
- not null -- 指示某列不能存储 NULL 值
- unique -- 保证某列的每行必须有唯一的值
- default -- 规定没有给列赋值时的默认值
- primary key -- not null 和 unique 的结合。确保某列(或两个列多个列的结合)有唯一标
识,有助于更容易更快速地找到表中的一个特定的记录 - foreign key -- 保证一个表中的数据匹配另一个表中的值的参照完整性
- check -- 保证列中的值符合指定的条件。对于MySQL数据库,对check子句进行分析,但是忽略
check子句 ,我们不太常用,就不说了
为何要有字段约束
- 保证数据的完整性
-
保证数据的有效性
完整性
我们有时候填表会发现有些是必填项,这里就是not null的作用,他要求这个表格不能为空,获取我们完整的信息
有效性
在这里我们假设一个个场景,要是张三的电话号码是123×××××××45,那么李四的电话号码绝对不会和张三一摸一样,这里就体现出unique的作用了
我们先创建一个表格,来仔细看看
create table books(
book_id char(10) not null,
book_name varchar(20) unique,
book_price int
);
非空约束 not null
非空约束比较简单,就是要求我们不能为空,命令为 not null
在上面我们就看到了这行代码 book_id char(10) not null, 这就是说book_id不可以为空
唯一约束 unique
这里也很简单,唯一 的意思就是各不相同,代码是book_name varchar(20) unique,
默认值约束 default
这个时定义默认值的,要是我们不定义,它是NULL
我们先测试一下
insert into types values (1,NULL,'测试');
insert into types (type_id,type_remark)values (1,'测试'); -- 部分列插入
从这里我们可以看出当我们不进行插入值时,列就会是默认值
主键约束 primary key
这里的主键约束相当于唯一约束和非空约束的集合,不过也会有一些另外的不同
- 主键约束 = 非空约束 + 唯一约束
- 主键约束也是一个标识
- 一个表只能有一个主键,一个主键可以包含一个或多个列
创建主键
我们最好每一张数据表都创建一个主键,后面我们用到索引的时候会说一下原因
方法一
create table Persons(
per_id char(10),
per_name char(12),
per_age int(3),
per_tele char(10) primary key -- 创建字段时指定
);
方法二
create table Persons(
per_id char(10),
per_name char(12),
per_age int(3),
per_tele char(10),
primary key(per_tele char(10)) -- 最后指定
);
看一看结果
删除主键
这里就体现出主键约束和其他的一些不同,我们删除时就不需要看具体的字段
alter table Persons drop primary key;
添加主键
alter table Persons modify per_tele char(10) primary key;
不能为空
不能相同
主键的自动增长
在实际生活中,我们可能会遇到这么一个问题,很多字段我们不能保证他们不为空或者是两两不同的,我们可以创建出一个额外的字段让他们好寻找,自然而然的就会以1、2、3、.......来标识,不过这也太麻烦了,我们出现了自动增长的形式
create table types(
type_id int primary key auto_increment,
type_name varchar(20),
type_remark char(11)
);
这个代码将type_id设置为自动增长主键
不过自动增长也有一些缺陷,要是我们删除一行,其他的type_id的值是不变的
这里我好好解释一下,只要我们添加了一行数据,他就会+1,即使我们后来删除了,它也不会 -1,是一直加的
联合主键
这里我先建一个数据表格,这张表中我们会发现,我们学生和课程只有在一起我们才能得到真实的成绩。所以这就出现了联合主键,联合主键,顾名思义就是多个主键联合形成一个主键组合,体现在联合。
我发现这里的字段都不能作为主键,但是学生和课程连在一起却可以,这就是联合主键
如何定义联合主键
mysql> create table grades(
-> stu_name char(10),
-> stu_class char(5),
-> stu_grade int,
-> primary key(stu_name,stu_class) -- stu_name 和 stu_class 一起 定义主键
-> );
这里面提示一下我们很少使用联合主键,我们可以额外提供一个字段作为识别
外键约束 foreign key
我们可能会疑惑什么是外键约束,我直接说一下,外键约束时联系多张表的约束,下面我用例子为大家说明一下
我们先创建两张表
-- 班级表
create table class(
id int primary key auto_increment,
name varchar(20)
);
-- 学生表
create table student(
id int primary key auto_increment,
name varchar(20),
classId int
);
每一个同学肯定是属于一个班级的,我们向往班级表中插入一些数据
insert into class values
(null ,'java1班'),
(null ,'java2班'),
(null ,'java3班'),
(null ,'java4班');
下面我们可以假设这样一个场景,有一名同学叫做 李白,在 java1班学习,我们可以这么记录
insert into student values (null,'李白',1); -- java1班 的id 是1
上面的情况很正常,但要是我们下面这么插入数据啊。
insert into student values (null,'杜甫',100);
我们没有id 是100的班级,但是我们也成功插入了,这就和实际产生了差异,这就引出了外键约束。外键很简单,要是两张表有联系就可以使用外键约束
正确使用外键
我们向把班级表和学生表删除,重新创建、
drop tables class,student;
创捷班级表
-- 创建班级表 不变
create table class(
id int primary key auto_increment,
name varchar(20)
);
-- 添加数据
insert into class values
(null ,'java1班'),
(null ,'java2班'),
(null ,'java3班'),
(null ,'java4班');
创捷学生表
外键的创建有些麻烦,我们先列出格式
foreign key(本表的字段) references 其他表的表名(其他表的表名的字段) -- ()号是存在的
create table student(
id int primary key auto_increment,
name varchar(20),
classId int,
foreign key(classId) references class(id) -- 解释这句话 我们定义一个外键,是classId,链接 class表中的 id 字段
);
当我们开始插入数据后,MySQL会自动帮助我们进行校验,我们来几次
insert into student values
(null,'李白',1),
(null,'刘备',2),
(null,'曹操',3),
(null,'杜甫',4);
但我们插入class中不存在的id时,出现错误
insert into student values (null,'错误',10);
外键约束的缺陷
我们使用外键会有一些小问题的。
- 效率有些低,我们插入数据时要查询另一张表的数据
- 不太能被关联的表,下面我用代码表示一下
drop table class;