MySQL学习:
https://blog.csdn.net/2301_80220607/category_12971838.html?spm=1001.2014.3001.5482
前言:
在上一篇我们已经学习了关于表操作的基础知识,比如创建表、删除表等,但是还有几个重点知识没有讲解,比如表的约束问题,今天这篇我们就重点讲解一下表的约束的原理和使用
在上篇的有些示例中我们已经注意到有一些列后面会跟着一些额外的内容,比如unique、comment等等,这些被称为表的约束,表的约束其实就是对数据的输入等做一定的要求,比如非空,唯一等,好比我们在登录一些软件时,有些选项比如密码等后面会加上*,告诉我们这个选项是必填的,也就是非空的,如果不填就点击提交登录就无法成功,这就是一种约束
所以说表的约束就是对数据库中的各项内容做出一定的约束条件,以确保用户输入的数据更合理合法,更具逻辑性
两个值:null(默认的)和not null(不为空)
默认的是null,也就是可以为空,但是在很多情况下有些字段是不能为空的,所以就需要not null来约束
案例:
创建一个班级表,包含班级名和班级所在的教室。
站在正常的业务逻辑中:
所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是 “ 约束 ” 。
create table myclass(
-> class_name varchar(20) not null,
-> class_room varchar(10) not null);
此时我们创建的表中两个列都有非空属性,如果我们在插入数据时没填数据就会报错
如图,如果我们只插入班级名,不插入班级所在教室就会报错
插入空值也会报错,所以说非空约束是必须要求我们插入值的,但是如果没有添加非空约束的话,就不是必须要插入值,且不插入时该列会默认为空值
默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择 性的使用默认值
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属性没有插入值时就会默认为张三,但是我们不能插入空值
列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了 解。
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;
前面我们在定义很多列时,列类型后往往会跟着一个长度,比如下面这个案例:
create table t3(
-> a int(10) unsigned,
-> b int(10) unsigned
-> );
可以看到 int(10), 这个代表什么意思呢?整型不是 4 字节码?这个 10 又代表什么呢?其实没有 zerofill 这个属性,括号内 的数字是毫无意义的。
如下我们插入一组数据:
插入后我们查看就是插入了两个简单的整数,并没有体现出int(10)括号中整数的价值,这是因为没有加列约束zerofill的缘故,只有加了这个列约束括号中的整数才能体现作用,下面我们将列a添上这个约束,然后再看一下有什么不同
这次可以看到 a 的值由原来的 1 变成 00001 ,这就是 zerofill 属性的作用,如果宽度小于设定的宽度(这里设置的是 5),自动填充 0 。要注意的是,这只是最后显示的结果,在 MySQL 中实际存储的还是 1 。为什么是这样呢?我们可以 用hex 函数来证明(hex函数的作用就是将我们的数字转为十六进制)
select a,hex(a) from t3;
可以看到数据库内部存储的还是1,00001只是设置了zerofill属性之后的一种格式化输出,这可以保证我们的表格是等宽的
主键: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;
create table t5(
-> id int unsigned,
-> course int unsigned comment '课程编码',
-> source int unsigned comment '成绩',
-> primary key(id,course) comment 'id和course为复合主键'
-> );
就比如这里两个字段被设置为复合主键,那么这两个字段都不能重复或为空
auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得 到一个新的不同的值。通常和主键搭配使用,作为逻辑主键
自增长特点:
案例:
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开始的
关于唯一键和主键的区别:
我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。乍 一听好像没啥区别,我们举一个例子:
假设有50个人在同一所高中的同一个班中,高中里每一个人都有一个学号,这个学号就是作为主键存在的,但是班主任为了方便管理班里的学生,他还给每个学生按成绩排了一个序号,这个序号也是唯一的,此时在设计表时,就可以把这个序号加上唯一性约束
通常我们将主键设计为与当前业务相关性不大的字段,这样在业务变更时就不需要连续变更主键中的内容,比如这里即使又考试了成绩发生了变动,我们的主键学号也不需要发生变动
案例:
创建一个带唯一性约束字段的表:
create table t8(
-> id int unsigned unique comment '唯一性约束,.不能重复,但可以为空',
-> name varchar(20)
-> );
不能重复:
可以为空:
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定 义外键后,要求外键列数据必须在主表的主键列存在或为null。
语法:
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字段不是主键吗?所以按理说它不能为空啊。
所以不管主表中的被依赖字段是主键约束还是唯一性约束,从表的约束字段都可以取空值
以上就是关于表的约束问题的全部内容,每一个都挺重要的,建议大家自己实操一遍
感谢各位大佬观看,创作不易,还望各位大佬带赞支持!!