数据类型

整数

名称占用空间(bit)范围(有符号)范围(无符号)
tinyint8-128 - 1270 - 255
smallint16-32,768 - 32,7670 - 65,535
mediumint24-8,388,608 - 8,388,6070 - 16,777,215
int32-2,147,483,648 - 2,147,483,6470 - 4,294,967,295
bigint64-9,233,372,036,854,775,808 - 9,223,372,036,854,775,8070 - 18,446,744,073,709,551,615

有符号范围为$(-2^{n-1}\sim2^{n-1}-1)$,无符号范围为$(0\sim2^{n}-1)$
整数类型可选unsinged属性,表示不能为负,该属性可以使正数范围提高一倍
有符号和无符号使用同样的存储空间,并且具有相同的性能
MySQL可以为整数类型指定宽度,例如int(8)。实际上对大多数应用并没有意义,它并不会限制类型的范围,只是规定了一些交互工具(MySQL命令行客户端)来显示字符个数的。对于存储计算来说int(1)int(10)是一样的

实数

MySQL支持实数类型为floatdoubledecimal
float为单精度浮点类型,使用32字节来储存,double为双精度浮点型,使用64字节来储存
上述两种类型为非精确类型MySQL提供精确类型decimaldecimal类型再可以指定decimal(m,n)其中m为总长度n为小数长度,其占用空间为m+1
因为decimal计算需要额外的开销,所以非精确小数计算使用floatdouble
精确计算则使用int类型乘小数点后$10^n$来使用
例如123.456需要精确3位,则使用int类型123456来储存,使用时直接除1000即可

字符串

字符串分定长字符串char和非定长字符串varchar
varchar为可变长度字符串它的优势在于仅适用必要的空间来存储数据,但是由于可变长度更新时会比原来长,则需要额外的扩容或更换存储位置。它适合用于平均长度与最大长度差距很大的场景
char为定长字符串,char以给定长度分配足够空间,如果需要保存的数据远远小于定义的长度则会造成空间浪费。他适合储存较短的字符串,因为定长所以不会产生内存碎片,性能高于varchar
如何储存取决于存储引擎的实现,并非所有的引擎都会按照此方式处理,以上为通常处理方式

数据类型的选择

更小更好

尽量选择适合业务范围的数据类型。更小的数据类型通常意味着占用更少的磁盘、内存和CPU缓存,处理时需要的占用的CPU周期更短。
字段扩容对数据库来说是一个繁重的操作,尽量避免线上对字段进行扩容

简单就好

复杂的数据类势必会占用更长的CPU周期,所以根据业务需求来选择一个相对简单的数据结构是必要的。
对于时间等复杂类型应选用内建数据结构来存储,而非使用字符串来存储

避免NULL值

如果查询中包含了可为NULL的列会使得索引、索引统计和值得比较变得更加复杂。当可为NULL的列被索引肯能需要更多的空间来索引,所以索引列尽量为非NULL列
直接将可为NULL的列改为NOT NULL可能并不能对性能带来大的提升