文章目录
- 0. 前言
- 1. 空属性
- 2. 默认值
- 3. comment
- 4. zerofill
- 5. 主键
- 6. 自增长
- 7. 唯一键
- 8. 外键
0. 前言
表的约束是保证插入的数据都是符合预期的,本质上通过技术手段,倒闭着使用者插入正确的数据。
反过来站在mysql
的视角,凡是插入的数据,都是符合数据约束的。
最终目标就是保证数据的完整性和可预期性。
为什么数据库需要对数据进行约束?
数据库是维护用户数据的最后一道防线。
用户从远端输入数据,通过网络传到服务器,服务器对数据做一系列处理,最后插入到数据库。
1. 空属性
在语言当中
null
和,都是表示
0
,而在数据库当中null
表示没有,表示有,只不过是空串
-
null
:默认的,可以为空 -
not null
:不为空null
可以理解为可选可不选,不选就空着;not null
表示为必选,不能空着
mysql">mysql> create table if not exists myclass (-> class_name varchar(20) not null,-> class_room varchar(20) not null,-> other varchar(20) -> );
当属性设置为not null
之后,插入数据的时候,不能为空
2. 默认值
如果某个数据经常出现,可以在一开始就指定好,用户指定就使用用户输入,没指定就采用默认的,这就是默认值
mysql">mysql> create table if not exists t1(-> name varchar(20) not null,-> age tinyint unsigned default 18,-> gender char(1) default '男'-> );
插入数据:
mysql">mysql> insert into t1 (name, age, gender) values ('小李', '20', '女');
mysql> insert into t1 (name, age, gender) values ('小王', '21', '男');
mysql> insert into t1 (name) values ('小默');
default
和not null
:mysql">mysql> create table t2(-> name varchar(20) not null,-> age tinyint default 18,-> gender char(1) not null default '男'-> );
mysql">mysql> insert into t2 (name, age, gender) values (null, 20, '男'); mysql> insert into t2 (age, gender) values (20, '男');
第一次插入指定为
null
,报错显示name
不允许为null
;第二次不插入
name
,报错显示没有默认值。所以当没有指定一列要插入,使用的是
default
;如果建表的时候,该对应列没有设置default
值,则无法直接插入
not null
和default
不冲突,是互相补充的:
- 当用户想插入时,
not null
进行约束- 当用户忽略这一列时,采用默认值(设置了默认值)
如果没有设置,则报错
在建表时如果没有指定默认值,mysql
会作出优化,自动添加默认值为null
mysql">mysql> create table t3(-> name varchar(20),-> age tinyint-> );
一般情况下,
not null
和default
不会同时设置,因为default
本身有默认值,不会为空
3. comment
comment
是对列进行描述说明的,没有实际含义,可以理解为注释
mysql">mysql> create table if not exists t4(-> name varchar(20) not null comment '用户名',-> age tinyint unsigned default 18 comment '年龄, 默认18岁',-> gender char(1) default '男' comment '性别, 默认男'-> );
mysql> show create table t4 \G
通过
desc
看不出描述信息:mysql">mysql> desc t4;
4. zerofill
zerofill
是关于显示方面的约束,在需要标准显示的场景使用
mysql">create table if not exists t5 ( a int unsigned not null, b int unsigned not null );
建立表的时候并没有指定int
后面括号的值,show create table t5 \G
查看:
mysql
会默认带上int(10)
,给b
增添zerofill
约束:
mysql">mysql> alter table t5 modify b int unsigned zerofill not null;
插入数据发现b
自动添加了很多0
,这就是zerofill
的作用,如果宽度小于设置的宽度,会自动填充0
。
这个宽度就是
int(width)
,括号里面的值;
zerofill
虽然会填充0
,但这只是显示的结果,最后在mysql
中存储的还是22
为什么
int unsigned
默认是10
:mysql">mysql> alter table t5 modify a int not null; mysql> alter table t5 modify b int unsigned not null;
这里发现有符号默认
11
,无符号默认10
,这是因为int
占四个字节,有符号的范围是-231 ~ 231-1,无符号的范围是0 ~ 232-1也就是21亿多和42亿多,最后表示出来也就是10位,
int
有符号需要一位来表示符号,所以为11
5. 主键
主键用来约束这个字段里面的数据不能重复,不能为空
就相当于我们注册账号,必须要有用户名,且不能重复
mysql">mysql> create table if not exists t8(-> id int unsigned primary key,-> password varchar(20) default '123'-> );
有主健约束的字段,不能重复
如果要去掉主键,直接drop
即可,因为一张表里面,只有一个主键
mysql">mysql> alter table t8 drop primary key;
如果在创建表之后,想要添加主键约束,要保证该列数据没有冲突,否则无法添加主键约束
mysql">alter table table_name add primary key(column_name); #添加主键约束
复合主键:
一个表只能有一个主键,不意味着只能添加给一列,可以添加到多列,这叫复合主键
mysql">mysql> create table student_scores (-> stu_id int unsigned,-> exam_id int unsigned,-> score int unsigned,-> primary key(stu_id, exam_id)-> );
这里两个pri
合起来才是一个主键,它们两个同时一样时,才触发主键约束
6. 自增长
auto_increment
对应的字段,如果不给值,会自动触发,系统从当前字段中已有的最大值+1
。
通常搭配主键使用。
任何一个字段要做自增长,前提是本身必须是一个索引值
自增长的字段必须是整数
一张表最大一个自增字段
mysql">mysql> create table if not exists t9 (-> id int unsigned primary key auto_increment,-> name varchar(20) not null default ''-> );
mysql">mysql> insert into t9 (name) values ('张三');
mysql> insert into t9 (name) values ('李四');
指定显示插入:
索引:
可暂时简单理解为书本多花几页纸来打印目录,为了读者更快定向找到书中的内容
7. 唯一键
一张表可能会有多个字段需要唯一性,但是一张表只能有一个主键;唯一键就可以解决一张表中多个字段需要唯一性约束的问题
mysql">mysql> create table t10 (-> id char(20) primary key,-> tel char(32) unique, -> name varchar(20) );
插入数据:
主键与唯一键的区别:
唯一键允许为空,空字段不做唯一性比较。
唯一键与主键并不冲突,主键保证记录的唯一性,唯一键保证指定的信息在表中不出现重复,一般建议将主键设置为与当前业务无关的字段。
8. 外键
mysql
是关系型数据库,表和表之间可能是会有关联的,外键就用于定义表和表之间的关系。
当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
mysql">mysql> create table if not exists class (-> id int unsigned primary key,-> name varchar(20) not null-> );mysql> create table if not exists student (-> id int unsigned primary key,-> name varchar(20) not null,-> telphone varchar(32) unique key,-> class_id int,-> foreign key(class_id) references class(id) #外键约束-> );
mysql">mysql> insert into class values (23402101, 'BD1');
mysql> insert into class values (23402102, 'BD2');
当有外键约束的时候,要插入不存在的班级编号是不允许插入的,当要删除这个主表还被其他从表关联的时候,是不允许删除的
外键的条件:
- 主表和从表产生关联关系
- 产生外键约束