Mysql数据类型设计思考

一、Mysql数据类型设计规范

1.1 选择更小的数据类型

一般情况下,在满足存储要求的基础上,尽量选择小的存储类型。例如:存储0~200,tinyint和bigint都可以存储,那么选择tinyint。原因:越小的数据类型运算速度更快,占用磁盘、内存以及CPU缓存更小

1.2 简单更好

简单的数据类型意味着操作需要更少的CPU周期。例如:整型比字符操作代价要小很多,因此字符集和排序规则使得字符比整型更加复杂。

1.3 避免使用NULL值

虽然NULL值也可以走索引,但对索引统计值比较逻辑以及内存使用等不太友好。
索引统计: 由于Mysql在执行查询优化时,会基于索引统计信息来选择最优的执行计划。当列中包含null值时,因null值不参与统计,会对执行计划产生影响,导致选择的执行计划不是最优的;
值比较逻辑: 对null值的操作只能使用is null, is not null,<=>,因此在进行范围查询或等值比较时,需要进行额外的处理;

选择步骤:

  1. 选择合适的大类型。比如:整型,字符串或时间
  2. 选择具体的小类型。比如:tinyint,bigint, datetime, timestamp等。

二、各种数据类型使用场景解析

2.1 整数和小数类型

2.1.1 整数

类型:tinyint, smallint, mediumint, int, bigint.分别占用1,2,3,4,8个字节的空间;
是否支持负数:支持
特点:
	1.默认是有符号。有unsigned【无符号】属性可以选择。加上unsigned意味着只能是正数,表示范围扩大一倍;
	2.有符号和无符号存储空间是相同的;
	3.int(n)int(m)存储空间是一样的,只不过显示宽度不一样而已.

2.1.2 小数

Mysql既支持精确类型,也支持不精确类型

精确类型:floatdouble
	- 使用标准的浮点运算进行【近似计算】
	- 适用于不需要精准计算的场景
不精确类型:decimal
	- 用于存储精确的小数
	- 适用于需要精准计算的场景。一般用于存储金额,但在大数据量情况下,可以将金额换算成分,存储到bigint里,解决浮点存储计算不精确和decimal精确计算代价高的问题。

decimal也有正负之分,通过unsigned来设置。decimal的格式为:decimal(P,D)
P: 表示有效数字位的精度。范围为1-65
D:表示小数点后的位数。范围为0-30Mysql要求D小于等于P

Decimal的存储:
在这里插入图片描述

2.2 字符串类型

char和varchar

char和varchar的区别:
前提:假设每个字符占用4个字节

  1. 存储方式:
    • char是定长字符串。当为char指定一个长度M时,会使用固定长度4M的空间来存储数据;
    • varchar是变长字符串。使用可变长度【实际字符串长度+存储字符串长度的空间】的空间来存储数据
  2. 使用场景
    • char更适合固定长度的字符串存储;
    • varchar更适合存储不定长度的字符串
varchar(10)场景下:"hh""hhh"占用多个字节?
	"hh": 2个字符 * 48个字节,由于8小于255,1个字节来存储字符串的长度,因此总体为9个字节
	"hhh": 3个字符 * 412个字节,由于12小于255,1个字节来存储字符串的长度,因此总体为13个字节

varchar(6)varchar(10)的区别:存储同样的字符串"hello"
1. 占用的磁盘空间大小是一样的。都是5个字符*4 + 1 = 21个字节;
2. 占用的内存空间不一样。MySQL通常会分配【固定大小的内存块】来保存内部值。尤其是使用临时表进行排序会操作时,会消耗更多的内存。在使用磁盘进行排序时,也是一样

blob和text:

两者都是为了存储大数据设计的字符串类型。blob采用二进制存储,text采用字符存储.
Mysql为了存储blob和text,专门分配存储区域来存储,然后在B+树上使用1-4字节的内存指针,指向存储区域。

2.3 时间类型

目前常用的两种时间格式为:datetime和timestamp。Mysql目前仅支持到毫秒级别的存储。

DateTime: 
	- 范围:1001-9999
	- 精度:秒
	- 与时区无关
	- 8字节存储
TimeStamp:
	- 范围:1970-2038
	- 精度:秒
	- 与时区有关
	- 4字节存储

使用场景:
1. 为时间创建索引或精确到毫秒:将时间转换为bigint类型存储,方便索引;
2. 对内存敏感的场景:使用TimeStamp
3. 对内存不敏感的场景:使用DateTime

其它数据类型用的比较少,如果要使用的话,可以查阅相关的资料即可。

三、Null值设计思考

建议:建表时,尽量不要将字段设置为null,给字段设置一个默认值

3.1 null生效和不生效情况

不生效情况查询运算符、like、between and、in、not in对null查询不生效
生效情况is null,is not null,<=>(安全等于,既可以判断null值,也可以判断普通数值,可读性差,不建议使用)

3.2 聚合函数和null值的结合

count(字段): 不会统计为null的数据;
count(*): 会统计为null的数据

3.3 null值和主键的结合

当字段设置为主键时,字段会自动被设置为not null

3.4 null值存储在B+树的哪里

考虑到主键不能为null,因此允许null值创建的索引都是非聚簇索引。设计Innodb的大叔定义Null值大小为最小的:
We define the SQL null to be the smallest possible value of a field.
因此,null值索引在B+树中的位置,应该是最靠近左边的。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃花猿

客官,赏点打酒钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值