目录
1. 表约束概述
2. 空属性(null/not null)
3. 默认值(default)
4. 列描述(comment)
5. zerofill
6. 主键(primary key)
7. 自增长(auto_increment)
自增主键的插入机制
设置AUTO_INCREMENT的原理
索引
定义
使用
思维导图如下:
1. 表约束概述
真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合 法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。
表的约束很多,这里主要介绍如下几个:
- null/not null
- default
- comment
- zerofill
- primary key
- auto_increment
- unique key
前面我们把列名称和类型都了解了,但是在实际查表得时候它们后面是什么东西呢?今天就来说一说~
2. 空属性(null/not null)
- null 表示列可以为空,not null 表示列不能为空。
- 通过 not null,可以设置某列数据在插入时必须填入具体值,否则会报错。例如注册账号时的某些必填信息。
示例:
create table if not exists myclass(class_name varchar(20) not null,class_room varchar(20) not null,other varchar(20)
);
在此示例中,class_name
和 class_room
列设置了 not null,因此这些字段不能为空;而 other
列默认允许为空。
- 我们发现other这一列我们是只写了一个varchar,没有指定not null,默认是null的,然后面加了一个default null
- 这里表示你想插就插,不插这一类就给默认值null。
插入数据测试:
某列设置了not null
- 必须要插具体值
- 不插因为后面没有默认值就报错
- 插入null也报错
设置默认为null,可以不插用的是后面带的默认值。
3. 默认值(default)
- default:当插入数据时,如果未指定该列的值,将使用默认值。
- 通过默认值,可以简化数据插入操作,提高数据一致性。
示例:
create table if not exists student(name varchar(20) not null,age tinyint unsigned default 18,gender varchar(10) default '男'
);
在此表中,age
默认值为 18,gender
默认值为“男”。当插入数据时,如未指定这些列的值,将使用默认值。
总结:default和not nul 并不冲突,而是互相补充的。
- 当用户指明这一列要插的时候,受null和not null 约束,要么插null,要么插合法数据。
- 总之用户指明这一列要插 ,not null来约束。
- 当用户忽略这一列的时候,如果设置了默认值使用默认值,如果没有就直接报错。
- 总结用户忽略这一列要插,default来约束。
最后再看age这一列只设置了default,我可以不插用default,插了用自己插入的,也可以为null因为没有用not null。
如果建表的时候, 不给某一列添加任何约束,我们会发现MySQL会对sql语句优化,默认会带上defalut null。所以不插入的时候在表示会显示null。
4. 列描述(comment)
- comment:用于给列添加注释说明,便于程序员和数据库管理员理解字段用途。
- 该属性不会对数据插入产生约束效果。
示例:
create table if not exists t5(name varchar(20) not null comment '用户的用户名',age tinyint unsigned default 18 comment '用户的年龄'
);
在表中并不会说因为不符合不让你插入。就相当于C/C++里的注释一样。
5. zerofill
- zerofill:在数字前补零,使显示字符长度符合指定的位数。
- 数据库存储的 数值不变,仅用于展示效果。
示例:
create table if not exists t6(a int unsigned not null,b int unsigned zerofill not null
);
打印查看,重点是这个10到底是什么?
现在正常插入没有什么问题
但是我们把b列添加zerofill的约束
在查刚才的表,发现b这一列变成这个样子,共10个位数,前面补0。
我们会发现,zero fill 还是挺形象的,填满 0~
如果以后你想显示出的是001,002就可以设置zerofill。
我们再来 按照16进制显示,验证一下:值不会改变,zerofill
只是一种格式化输出
select a,hex(b) from t6; #指定显示某列
如果以后你想显示出的是001,002就可以设置zerofill。
还有一个细节,为什么int()后面带的是10?更准确的是为什么 unsigned int()是10,int()是11?
int占4个字节,有符号取值范围 -2^31 - 2^31-1,无符号取值范围 2^32-1,无论是 2^31,还是 2^32 转成10进制是21亿多,42亿多,这么大的数字其实最后表示处理也就是10位,8位千万,9位亿,10位十亿。
用10就可以把所有整数数据位全都表示出来。
int 多出一个1是因为它是有符号的,多一位标识符号位。
6. 主键(primary key)
- primary key:用于标识表中的唯一记录,不允许重复或为空。
- 表中最多只能有一个主键列。
- 主键可以通过复合主键的方式使用多列联合唯一标识。
示例:
create table if not exists t8(id int unsigned primary key,name varchar(20) not null
);
在此示例中,id
被设为主键,数据库自动为主键列添加 not null 约束。
- 主键约束对于程序员来讲,未来想往这个表里面插对应插入的数据主键列不能冲突,一旦冲突不让你插入,所以倒逼程序员插的时候尽量不要出现主键冲突。
- 其次站在mysql视角凡是插入这个表里面的数据主键一定是不冲突的。这样的好处是根据主键绝对能拿出来确定的一条记录!--唯一性
- 有了主键可以有针对性的对数据进行增删查改
创建主键有两种方法:
- 创建表的时候就把主键设置好
- 表建好之和但没有主键,可以追加主键
第一种刚才就是,下面看第二种如何做,首先原始表中的主键先去掉,然后再添加主键:
删除 | 添加主键
- 虽然一张表中最多只能有一个主键,但是并不意味着一个表中的主键只能添加给一列!
- 也就是说一个主键可以被添加到一列,或者多列上。
- 一个主键被添加到多列上的数据我们就叫做复合主键
在创建表的时候,在所有字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以使用复合主键。
下面创建表我们让两列合起来充当一个主键,如创建一张表让一个学生不能选修同样的课程。
create table t9(id int unsigned,course_id int unsigned comment '课程编号',score tinyint unsigned comment '课程得分',primary key(id,course_id));
可以看到id和course_id 都叫做主键。
可是刚才不是说了一张表只有一个主键吗,这里我怎么看到有两个主键啊?
有两个PRI,但并不证明有两个主键!而是这两个都是主键,两个都是主键如何理解呢?它们两个合起来才是一个主键!
现在是1234这个同学选了编号40的课得到90分,这没什么问题
但是我们不允许,同一个同学选同一个课!出现主键约束了。它是把id和course_id作为一个整体的。
- 换言之,可以选择一列作为主键,也可以选择多列作为主键
- 但是多个合起来做一个主键,都不一样可以插,有一个不一样可以插,只有多个同时和历史数据一样才会出现主键冲突。 这就是复合主键。
- 复合主键理解:将多列看成一个整体,全部同时冲突,才会约束
- 后面可以支持通过主键进行快速查找。
7. 自增长(auto_increment)
- auto_increment:字段自动增长,从当前最大值加 1,通常配合主键使用,确保值唯一。
自增长的特点:
- 任何一个字段要做自增长,前提:本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
示例:
create table t10(id int unsigned primary key auto_increment,name varchar(20) not null
);
在此示例中,id
列自增长,无需显式插入,系统自动为其赋值。
插入时,我们可以指定插入其他列,id这一列就不管了。可以看到虽然我并没有告诉id要插什么,但是id是自动帮我们插入的,并且是增长的。
和别人不冲突并且连续的,这就是自增长主键。
当我们指定id要插入的时候,也能插进行。然后再插入id相同值的时候,确实能够履行主键的职责发生主键冲突。
当把重复的值去掉之后也能插入,发现它是从1000开始自增
自增主键的插入机制
- 默认行为:自增主键在插入时若未设置任何默认值,则默认从1开始插入。
- 手动设置起始值:如果手动插入一个新的起始值,且该值大于历史值,则自增主键将从新的起始值开始进行插入。
设置AUTO_INCREMENT的原理
- 表内外约束:创建表时,除了在表内设置
auto_increment
约束外,还可以在表外设置auto_increment
的值,这代表下一次插入的起始值。 - 插入时更新起始值:当插入一个值时(如1000),系统会自动更新表外的
auto_increment
值,使其成为下次插入的起始值。
创建带有自增主键的表示例
获取上次插入的AUTO_INCREMENT值
- 单条插入:可以使用
last_insert_id()
函数来获取最后一次插入的AUTO_INCREMENT
值。 - 批量插入:获取的是批量插入中的第一个
AUTO_INCREMENT
值。
select last_insert_id();
索引
定义
- 物理存储结构:在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构。
- 组成:索引是某个表中一列或若干列值的集合,以及相应的指向表中物理标识这些值的数据页的逻辑指针清单。
使用
- 快速定位:索引提供了指向存储在表的指定列中的数据值的指针,并根据指定的排序顺序对这些指针排序。
- 提高查询效率:数据库使用索引以找到特定值,然后顺指针找到包含该值的行,从而使得对应于表的SQL语句执行得更快。