MySQL学习:
https://blog.csdn.net/2301_80220607/category_12971838.html?spm=1001.2014.3001.5482
前言:
在上一篇我们已经学习了关于表操作的基础知识,比如创建表、删除表等,但是还有几个重点知识没有讲解,比如表的约束问题,今天这篇我们就重点讲解一下表的约束的原理和使用
目录
1. 表的约束的概念
在上篇的有些示例中我们已经注意到有一些列后面会跟着一些额外的内容,比如unique、comment等等,这些被称为表的约束,表的约束其实就是对数据的输入等做一定的要求,比如非空,唯一等,好比我们在登录一些软件时,有些选项比如密码等后面会加上*,告诉我们这个选项是必填的,也就是非空的,如果不填就点击提交登录就无法成功,这就是一种约束
所以说表的约束就是对数据库中的各项内容做出一定的约束条件,以确保用户输入的数据更合理合法,更具逻辑性
2. 表的约束的类型
2.1 空属性
两个值:null(默认的)和not null(不为空)
默认的是null,也就是可以为空,但是在很多情况下有些字段是不能为空的,所以就需要not null来约束
- 如果班级没有名字,你不知道你在哪个班级
- 如果教室名字可以为空,就不知道在哪上课
create table myclass(
-> class_name varchar(20) not null,
-> class_room varchar(10) not null);
此时我们创建的表中两个列都有非空属性,如果我们在插入数据时没填数据就会报错
如图,如果我们只插入班级名,不插入班级所在教室就会报错
插入空值也会报错,所以说非空约束是必须要求我们插入值的,但是如果没有添加非空约束的话,就不是必须要插入值,且不插入时该列会默认为空值
2.2 默认值
create table t1(
-> name varchar(20) not null,
-> age tinyint unsigned default 0,
-> sex char(2) default '男'
-> );
比如这个案例,我们将age和sex设置了默认值,此时我们再插入数据时,如果这两个属性没有被插入值就会使用默认值
默认值和空属性是可以同时使用的,两者并不冲突,比如 name varchar(20) not null default '张三';
这就是一个典型的默认值和空属性同时使用的案例,当我们插入数据时,如果name属性没有插入值时就会默认为张三,但是我们不能插入空值
2.3 列描述
create table t2(
-> name varchar(32) not null,
-> age tinyint unsigned default 18 comment '这是年龄',
-> sex char(2) default '男' comment '这是性别'
-> );
比如这个示例,我们创建的表t2中有列描述,但需要注意的是列描述只在表创建语句中保存,所以我们直接通过desc查看时是查看不到什么的
desc t2;
查看表创建语句时可以看到我们的描述字段:
show create table t2;
2.4 zerofill
前面我们在定义很多列时,列类型后往往会跟着一个长度,比如下面这个案例:
create table t3(
-> a int(10) unsigned,
-> b int(10) unsigned
-> );

插入后我们查看就是插入了两个简单的整数,并没有体现出int(10)括号中整数的价值,这是因为没有加列约束zerofill的缘故,只有加了这个列约束括号中的整数才能体现作用,下面我们将列a添上这个约束,然后再看一下有什么不同
select a,hex(a) from t3;
可以看到数据库内部存储的还是1,00001只是设置了zerofill属性之后的一种格式化输出,这可以保证我们的表格是等宽的
2.5 主键
主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多有一个主键,主键所在的列通常为整数类型
案例:
- 创建表时直接在字段上指定主键
create table t4(
-> id int unsigned primary key comment '学号不能为空',
-> name varchar(20) not null
-> );
- 主键约束:主键对应的字段中不能重复,一旦重复就会发生错误
- 追加主键:当表创建好但是没有主键时,可以追加主键,但进行追加主键操作前需要先确保我们的数据库中,要确认为主键的这个字段中不要有重复和空值的情况
alter table 表名 add primary key(字段列表);
- 删除主键
alter table 表名 drop primary key;
- 复合主键:在创建表的时候,在所有字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键, 可以使用复合主键。
create table t5(
-> id int unsigned,
-> course int unsigned comment '课程编码',
-> source int unsigned comment '成绩',
-> primary key(id,course) comment 'id和course为复合主键'
-> );
就比如这里两个字段被设置为复合主键,那么这两个字段都不能重复或为空
2.6 自增长
auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得 到一个新的不同的值。通常和主键搭配使用,作为逻辑主键
自增长特点:
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
案例:
create table t6(
-> id int unsigned primary key auto_increment,
-> name varchar(10) not null default ''
-> );
在这个案例中id被设为主键,那它不能为空且不能重复,但同时我们也将它设为自增长,那么会有什么不同呢?我们插入几组数据检验一下
如上我们插入了两组数据,但是主键列没有插入值,但是没有报错,我们查看表中数据,发现id自动有了1和2,这就是自增长的作用,在我们没有往这个字段中写入值时,它会自动在前一个值的基础上加1
- 此外我们也可以查看自增长字段已经到多少了
select last_insert_id();
- 我们也可以设置我们自增长的初始值:
比如上面那个案例,我们可以将我们的id的自增长初始值设为500
create table t7(
-> id int unsigned primary key auto_increment,
-> name varchar(20)
-> )auto_increment=500;
然后再插入数据,我们就会发现我们的自增长是从500开始的
2.7 唯一键约束
- 一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多 个字段需要唯一性约束的问题。
- 唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
假设有50个人在同一所高中的同一个班中,高中里每一个人都有一个学号,这个学号就是作为主键存在的,但是班主任为了方便管理班里的学生,他还给每个学生按成绩排了一个序号,这个序号也是唯一的,此时在设计表时,就可以把这个序号加上唯一性约束
通常我们将主键设计为与当前业务相关性不大的字段,这样在业务变更时就不需要连续变更主键中的内容,比如这里即使又考试了成绩发生了变动,我们的主键学号也不需要发生变动
案例:
创建一个带唯一性约束字段的表:
create table t8(
-> id int unsigned unique comment '唯一性约束,.不能重复,但可以为空',
-> name varchar(20)
-> );
不能重复:
可以为空:
2.8 外键
语法:
foreign key (字段名) references 主表(列)
案例:
id | name | class_id |
100 | 张三 | 10 |
101 | 李四 | 20 |
id | name |
10 | 高三三班 |
20 | 高三四班 |
如上两个表,它们之间是存在者一些关系的,学生表中的班级编号字段(class_id),是依赖于班级表中的编号字段的(id),如果一个学生的class_id在班级表的id字段中不存在,按理说就是错误的,因为一个学生不可能隶属于一个不存在的班,也就是说学生表的class_id字段是依赖于班级表中的id字段的,这种依赖关系就叫做外键依赖
生活中这种依赖关系是非常常见的,我们需要注意的是被依赖的表中是要有主键约束或unique字段的,比如上面这个班级表中的id字段实际上就应该作为主键存在的
下面我们来设计一下上面的那个案例:
首先先来设计一下主表(班级表):
create table myclass(
-> id int unsigned primary key comment '班级id作为主键存在',
-> name varchar(20)
-> );
再创建从表:
create table Stu(
-> id int primary key,
-> name varchar(20) not null,
-> class_id int unsigned,
-> foreign key(class_id) references myclass(id)
-> );
- 正常插入数据:
注意我们上面的插入顺序一定是要先插入班级表,再插入学生表,准确点说是插入学生表中的班级id一定是在班级表中已经有的,如果班级表中没有这个班级就无法插入
- 比如插入一个班级id为30的学生,因为没有这个班级,所以插入会不成功
- 当我们不知道一个学生所属班级的时候,我们可以将他先设为空
有意思的是班级表中的id字段不是主键吗?所以按理说它不能为空啊。
所以不管主表中的被依赖字段是主键约束还是唯一性约束,从表的约束字段都可以取空值
3. 总结
以上就是关于表的约束问题的全部内容,每一个都挺重要的,建议大家自己实操一遍
感谢各位大佬观看,创作不易,还望各位大佬带赞支持!!