阅读原文:数据库优化第一步:数据类型html
为何选择合适的数据类型很重要?由于数据类型会影响存储空间的开销,也会影响数据的查询效率,能够说这是你优化数据库的第一步要作的事情。mysql
本文的前提环境是:MySQL 5.7 , UTF-8 Unicodesql
表明的是字符,不管英文或中文 均可以存储10个字符。数据库
数字5并非表明存储的长度,int型的长度是4字节固定的,括号里的数字仅仅表明最小显示的宽度。优化
其实当咱们长度超过5的时候它是没用的,和没有设置同样,当长度没有超过5时,而且设置了zerofill(填充零),它会在不足的从左侧填充零,假如插入了数字 22 ,那么显示的是 00022 (navicat不显示,可在cmd中查看)。ui
因此你指定的数字和它的大小及存储的空间没有关系。spa
int有符号数最小值:.net
-2 1 4 7 4 8 3 6 4 8
总共11位设计
2 1 4 7 4 8 3 6 4 7
总共10位指针
因此你懂得…… 其它的整数类型以此类推。
由于咱们使用的是 InnoDB存储引擎,内部的行存储格式没有区分固定长度和可变长度列(全部数据行都使用指向数据列值的头指针),所以在本质上,使用固定长度的CHAR列不必定比使用可变长度VARCHAR列简单。
Value | CHAR(4) | 实际存储 | VARCHAR(4) | 实际存储 |
---|---|---|---|---|
'' | ' ' | 4 bytes | '' | 1 bytes |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdef' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
能够用上表来表示,当定义char时,无论你存入多少字符,都会占用到你定义的字符数,而用varchar时,则和你输入的字符数有关,会多一到两个字节来记录字节长度,当数据位占用的字节数小于255时,用1个字节来记录长度,数据位占用字节数大于255时,用2个字节来记录长度,还有一位来记录是否为nul值
我平时会把这篇总结当作一个字典,每次设计数据库时忘记了会拿出来看下。
MySQL支持的数据类型主要分为3类:
1byte = 8bit 关于位的计算可参考个人另外一篇文章《位运算》
类型 | 存储(byte) | 符号 | 最小值(公式) | 最大值(公式) |
---|---|---|---|---|
tinyint | 1 | 有 | -128 (-27) | 127 (27-1) |
<br/> | <br/> | 无 | 0 | 255 (28-1) |
smallint | 2 | 有 | -32768 (-215) | 32767 (215-1) |
<br/> | <br/> | 无 | 0 | 65535 (216-1) |
mediuint | 3 | 有 | -8388608 (-223) | 8388607 (223-1) |
<br/> | <br/> | 无 | 0 | 16777251 (224) |
int | 4 | 有 | -2147483648 (-231) | 2147483647 (231-1) |
<br/> | <br/> | 无 | 0 | 4294967295 (232-1) |
bigint | 8 | 有 | -9223372036854775808 (-263) | 9223372036854775807 (263-1) |
<br/> | <br/> | 无 | 0 | 18446744073709551615 (264-1) |
使用方式:即DECIMAL(M,D)
M的取值范围为1~65,取0时会被设为默认值,超出范围会报错。
D的取值范围为0~30,并且必须<=M,超出范围会报错。
因此,很显然,当M=65,D=0时,能够取得最大和最小值。
例如: DECIMAL(5,2)
范围: -999.99 到 999.99
若是存储时,整数部分超出了范围(如上面的例子中,添加数值为1000.01),就会报错,不容许存这样的值。
若是存储时,小数点部分若超出范围,就分如下状况:
MySQL数据类型 | 含义 |
---|---|
float(m,d) | 单精度浮点型 8位精度(4字节) m总个数,d小数位 |
double(m,d) | 双精度浮点型 16位精度(8字节) m总个数,d小数位 |
浮点数是用来表示实数的一种方法,它用 M(尾数) * B( 基数)的E(指数)次方来表示实数,相对于定点数来讲,在长度必定的状况下,具备表示数据范围大的特色,但同时也存在偏差问题。若是但愿保证值比较准确,推荐使用定点数数据类型。
例如: float(7,4)
范围: -999.9999 到 999.9999
MySQL保存值时进行四舍五入,所以若是在FLOAT(7,4)列内插入999.00009,近似结果是999.0001。
float和double中的M和D的取值默认都为0,即除了最大最小值,不限制位数。容许的值理论上是-1.7976931348623157E+308~-2.2250738585072014E-30八、0和2.2250738585072014E-308~1.7976931348623157E+308。
M、D范围:
FLOAT和DOUBLE中,若M的定义分别超出7和17,则多出的有效数字部分,取值是不定的,一般数值上会发生错误。由于浮点数是不许确的,因此咱们要避免使用“=”来判断两个数是否相等。
字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。
类型名称 | 说明 | 存储需求 |
---|---|---|
CHAR(M) | 固定长度的非二进制字符串 | M字符,1<=M<=255 |
VARCHAR(M) | 变长的非二进制字符串 | M字符,1<=M<=21845(utf8)或16383(utf8mb4),最大上线65535字节 |
ENUM | 枚举类型,只能有一个枚举字符串值 | 1或2个字节,取决于枚举值的数目(最大值是65535) |
SET | 一个设置,字符串对象能够有零个或多个SET成员 | 1,2,3,4或8个字节,取决于集合成员的数量(最多64个成员) |
TINYTEXT | 很是小的非二进制字符串 | L+1个字节,这里L<28 |
TEXT | 小的非二进制字符串 | L+2个字节,这里L<216 |
MEDIUMTEXT | 中等大小的非二进制字符串 | L+3个字节,这里L<224 |
LONGTEXT | 大的非二进制字符串 | L+4个字节,这里L<232 |
MySQL数据类型 | 字节长度 | 含义(格式) | 范围 |
---|---|---|---|
date | 3 | 日期 YYYY-MM-DD | '1000-01-01'到 '9999-12-31' |
time | 3 | 时间 HH:MM:SS | '-838:59:59'到'838:59:59' |
year | 1 | 年YYYY | 1901到2155 |
datetime | 8 | 日期时间 YYYY-MM-DD HH:MM:SS | '1000-01-01 00:00:00'到'9999-12-31 23:59:59' |
timestamp | 4 | 自动存储记录修改时间YYYY-MM-DD HH:MM:SS | '1970-01-01 00:00:01' UTC 到'2038-01-19 03:14:07' UTC |
这里指的是数据列的数据类型,在选择合适的数据类型时,咱们应知足如下条件:
欢迎关注公众号交流!
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/ref...
https://www.edureka.co/blog/m...