您的位置:首页 > 数据库 > MySQL

MySQL数据类型理解和优化

2017-11-15 11:14 323 查看
MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。

几个简单的设计原则

更小的通常更好:一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型更快,占用更少的磁盘,内存和CPU缓存,并且处理时需要的CPU周期更少。

简单就好:简单数据类型的操作性能更好。整形比字符串操作的代价更低。比如,用整形存储IP地址而不是字符串(工作中经常看到使用VARCHAR类型存储IP地址,它们实际上是32位无符号整数,不是字符串,用小数点将地址分成四段表示只是为了容易阅读。MySQL提供了INET_ATON()和INET_NTOA()函数进行转换),使用MySQL内建的类型而不是字符串。

避免使用NULL :NULL是列的默认属性,如果定义表结构时没有指定列为NOT NULL,默认都是允许为NULL的。通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。包含NULL值的列使得索引,索引统计和比较值都更复杂,对MySQL来说更难优化。

整数类型

MySQL可以使用这几种整数类型:TINYINT(8位),SMALLINT(16位),MEDIUMINT(24位),INT(32位),BIGINT(64位)。整数类型有可选的UNSIGNED属性,表示不允许负值,这可以使正数的上限提高一倍。

MySQL可以为正数类型指定宽度,比如INT(10),其实这样指定没有什么意义,它不会限制值的范围,对于存储和计算来说,INT(1)和INT(10)是相同的。它的作用只是用来显示字符的个数。

实数类型

实数是带有小数部分的数字。MySQL有FLOAT,DOUBLE和DECIMAL类型可使用,FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似计算(具体实现依赖于所使用的平台),DECIMAL类型用于存储精确的小数。

使用DECIMAL类型需要额外的空间和计算开销,数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL,根据小数的位数剩以相应的倍数即可。

字符串类型

VARCHAR和CHAR是两种最主要的字符串类型。存储引擎存储CHAR和VARCHAR值的方式在内存中和在磁盘上可能不一样,所有MySQL服务器从存储引擎读出的值可能需要转换为另一种储存格式。

VARCHAR

VARHCAR类型用来存储可变长字符串,是最常见的字符串数据类型。它仅使用必要的空间,越短的字符串使用越少的空间,VARCHAR节省了存储空间,所以对性能也有帮助。但是由于是变长,在UPDATE时需要做额外的工作,因为有可能更新使行变得比原来更长。

VARCHAR需要额外使用1或2个字节记录字符串的长度,列的最大长度小于等于255字节时,额外使用1一个字节表示长度,否则使用2个字节。比如VARCHAR(10)需要11个字节的存储空间,VARCHAR(1000)需要1002个字节的存储空间。

下面这些情况适合使用VARCHAR:更新频率较少;存储的字符串值长度不确定
4000
且最大长度比平均长度大很多;使用了类似UTF-8这样的复杂字符集(一个英文字符等于一个字节,一个中文(含繁体)等于三个字节)。

CHAR

CHAR类型是定长的,MySQL总是根据定义的字符串长度去分配空间。CHAR值会根据需要采用空格进行填充来补长,值得注意的是MySQL取出CHAR会删除CHAR类型值的末尾空格。

CHAR适合存储很短的字符串,或者所有值都接近同一个长度。对于经常UPDATE的数据,CAHR也比VARCHAR更合适,因为定长不容易产生碎片。CHAR也不需要额外的字节记录字符串的长度,比如CHAR(1)只需要一个字节,VARCHAR(1)则需要两个字节,一个记录值,一个记录值的长度。

BINARY和VARBINARY

BINARY和VARBINARY存储的是二进制字符串。二进制字符串存储的是字节码而不是字符。 填充也不一样,CHAR用空格填充,BINARY用\0(零字节)而不是空格,在检索时也不会去掉填充值(如果需要检索时保持值不变,则要特别注意这点)。

当需要存储二进制数据,并希望使用字节码而不是字符串进行比较时,这两个类型非常有用。二进制比较不仅仅体现在大小写敏感上,更重要的是二进制比较比字符串比较简单很多,快很多。

BLOB和TEXT类型

BLOB和TEXT都是为了存储很大的数据而设计的字符串数据类型,BLOB采用二进制存储,TEXT采用字符串存储。

TEXT类型下有:TINYTEXT,SAMLLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;

BLOB类型下有:TINYBLOB,SAMLLBLOB,BLOB,MEDIUMBLOB,LONGBLOB。

MySQL把BLOB和TEXT值当作一个独立的对象处理。存储引擎在存储时会对它们做特殊处理。当值太大时,InnoDB存储引擎会使用专门的“外部”存储区域来存储实际值,此时每个值在行内会存储一个1~4字节的指针,通过该指针指向外部存储区域的实际值。

ENUM枚举类型

枚举列可以把一些不重复的字符串存储成一个预定义的集合。MySQL在内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”映射关系的“查找表”。

枚举的字符串列表是固定的,添加或删除必须使用ALTER TABLE。

日期和时间类型

MySQL可以使用很多类型保存日期和时间值,比如YEAR和DATE。MySQL能存储的最小时间单位是秒。大部分时间类型都有各自的用途,不存在最佳选择的问题。MySQL提供两种相似的日期类型:DATETIME和TIMESTAMP。

DATETIME

这个类型能保存从1001年到9999年,精度为秒。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关。使用8个字节的存储空间。默认情况下,MySQL以一种可排序的,无歧义的格式显示DATETIME值,例如“2017-11-16 10:53:00 ”。这是ANSI标准定义的日期和时间表示方法。

TIMESTAMP

时间戳类型保存了从1979年1月1日午夜(格林尼治标准时间)到现在的秒数,它和UNIX时间戳相同。TIMESTAMP只使用4个字节的存储空间,只能表示1970年到2038年的范围。MySQL提供了FROM_UNIXTIEM()函数把UNIX时间戳转换为日期,提供了UNIX_TIMESTAMP()函数把日期转换为UNIX时间戳。

TIMESTAMP显示的值依赖时区,MySQL服务器,操作系统,以及客户端连接都有时区设着,如果在多个时区存储或访问数据,TIMESTAMP和DATATIME的行为很不一样。前者提供的值和时区有关,后者直接保留文本表示的日期和时间。通常应该尽量使用TIMESTAMP,因为它比DATETIME空间效率更高。

位数据类型

MySQL有少数几种存储类型使用紧凑的位存储数据。所有这些类型,不管底层存储格式和处理方式如何,从技术上来说都是字符串类型。

BIT

BIT(1)定义一个包含单个位的字段,BIT(2)存储2个位,以此类推。BIT列的最大长度时64个位。BIT的行为因存储引擎而异,且行为令人费解,所以应该谨慎使用BIT类型,对于大部分应用,最好避免使用这种类型。

SET

SET在MySQL内部是以一系列打包的位的集合来表示的,能够有效的利用存储空间。它的主要缺点是改变列的定义代价较高,需要ALERT TABLE。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: