数据类型

整形

最小的tinyint占用1字节,最大的bigint占用8字节 (1、2、3、4、8)

取值范围255、65535、1600万、42亿、超级大

对于整形,其实不用太苛刻,即便用错了,差距也不会太大

但作为严谨的程序员/DBA,选择最合适的类型即可

INT(11),11是修饰符,不是长度限制,和zerofill配合使用,左侧补零。而Oracle中number(11)则是长度限制

int(8),存储1024,显示00001024

 

字符串

char,固定长度,最高255字节

varchar,可变长度,最高65535字节

在不跨越255字节的情况下,增加varchar列长度可以实现inplace,不需要拷贝(迁移)源数据

binary/varbinary分别是char/varchar的二进制存储方式

char类型总是在底层存储时用\0补足长度,而varchar则会删除尾部空格

但是读取数据时,char则不会显示尾部的空格,而varchar则会显示尾部空格

sql_mode='PAD_CHAR_TO_FULL_LENGTH' 控制char读取时是否补足空格

varchar是变长类型,需要额外1-2字节(整体而言,其实这个代价很小)

理论山,一个表中所有varchar列的总长度是65535字节。但实际上是65533,因为要减去上述提及的1-2字节

字符集(charset),字符串的编码规则

校验集(collation),定义字符排序顺序,控制各个字符和字符串如何比较的规则

MySQL8.0开始,默认使用utf8mb4字符集

字符集是utf8mb4时,实际可存储字符数:FLOOR(65533/4)=16383

议优先选择varchar类型,少用char类型

够用前提下,长度越小越好

长度越长,排序时会消耗更多的内存

 

日期、时间

5.6.4开始支持毫秒,不同长度占用0-3字节

5.6.6开始,datetime也支持current_timestamp

一个表里,可以有多个datetime/timestamp列自动更新

year,date,time,datetime,timestamp分别占用1,3,3,8,4字节

5.6开始,强烈建议采用datetime类型

日期转换运算

    (datetime_col as DATE)

    ct now()+0 自动转成bigint unsigned

 

长文本、大对象

如果需要存储JSON数据,可以采用JSON类型,还有配套的JSON函数,存取性能也比text更好

超长字段有可能会发生off page(overflow)存储

非常不推荐使用的数据类型,无法避免时则尽量独立子表存放

对text列排序时,实际排序长度是max_sort_length字节

 

float、double、decimal

个人看法,统统用decimal就好了

float & double都是占用4~8字节

DECIMAL

    进制浮点型,高精度计算

    5(默认10),D最大30(默认0)

    30个字节

 

枚举,ENUM

value_list数量不超过255时,占用1字节,超过255时,占用2字节,最多65535个

表面上是用字符型表示,但实际底层采用INT来存储,显示时再转回之前存储表示的值

所以,本质上可以直接用TINYINT/SMALLINT代替

 

json

MySQL5.7起支持json

其实MySQL底层仍采用blob类型,server层增加json相关函数及约束,因此各个存储引擎都支持json

json类型不能设定长度限制,允许为null,但是不能设定默认值

元素搜索严格区分变量类型,例如整形不引号,而字符串必须加引号

key的长度最多65535字符

json列通常会增加相应的虚拟列,再对虚拟列创建索引,提高查询效率

MySQL5.7中json只更新部分值时,binlog会记录整列值,8.0开始才会记录变更的那部分值

 

类型选择

最大限度减少I/O请求

让数据表每行长度越小越好

有text/blob等大列时,尽量拆分到独立子表中

经常更新的列和不经常更新的列分开存储

更新前后的长度也尽可能不要变大

 

当列类型默认为NULL时,可能存在什么问题?

排序时,NULL值无法真实反应排序规则

count(*)时可以统计NULL行,而count(c1)则会略过NULL行

对NULL列求DISTINCT、COUNT(DISTINCT)值时也会出乎意料,二者不相等

有索引时,NULL值总是存储在索引树的最左边,更容易造成索引倾斜

 

类型隐式转换

对NULL进行比较时,只能是IS [NOT] NULL,或者<=> NULL(其他情况无法正确计算,也无法使用索引)

向字符串列传入整型比较时,整型会被隐式转换成字符串(无法使用索引)

TIMESTAMP/DATETIME列和整型比较时,整型会自动转换成日期时间型(5.6后可以使用索引)

字符串列和0比较时,全部字符串行会匹配上(结果出乎意料)

 

posted @ 2019-08-16 17:02  AllenHU320  阅读(148)  评论(0编辑  收藏  举报