1.选择优化的数据类型的标准
1)更小的通常更好。
一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。
2)简单就好
简单数据类型的操作通常需要更少的CPU周期
3)尽量避免NULL
许多表都包含可为NULL(空值)的列,记事应用程序并不需要保存NULL也是如此,这是因为可为NULL是列的默认属性。通常情况下,最好制定列为NOT NULL,除非真的需要存储NULL。
2.基本的数据类型
1)整数类型
TINYINT(8位存储空间)、SMALLINT(16位存储空间)、MEDIUMINT(24位存储空间)、INT(32位存储空间)、BIGINT(63位存储空间),对应的值的存储范围为-2N-1至2N-1-1,其中N是存储空间的位数。
整数类型有可选的UNSIGNED属性,表示不允许负值,这大致可以使证书的上限提高一倍。例如:TINYINT可以存储的范围是0~255,而TINYINT存储的范围是-128~127。 有符号和无符号类型使用相同的存储空间,并具有相同的性能,因此可以根据实际情况选择合适的类型。
你的选择决定了MySQL怎样在内存和磁盘中存储数据。然而整数据算一般使用64位的BIGINT整数,即使在32位的环境也是如此。一些聚合函数是例外,他们使用DECIMAL(DECIMAL不属于浮点数类型,可以在定义时划定整数部份以及小数部分的位数。使用精确小数类型不仅能够保证数据计算更为精确,还可以节省储存空间,例如百分比使用decimal(4,2)即可。存储数据范围是:-10^38~10^38-1 的固定精度和小数位的数字。一个decimal类型的数据占用了2~17个字节。)或者DOUBLE进行计算。
MySQL可以为整数类型指定宽度,例如:INT(11),但是这对大多数应用是没有意义的。他不会限制指的合法范围,只是规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。
2)实数类型
DECIMAL、FLOAT(4字节存储)、DOUBLE(8字节存储)
DECIMAL可以用来存储比BIGINT还大的整数。DECIMAL用来存储精确的小数。在MySQL5.0和更高版本,DECIMAL支持精确计算。MySQL以及更早的版本使用浮点运算实现DECIMAL的计算。这样会因为精度损失导致一些奇怪的结果。
因为CPU不支持DECIMAL直接运算,所以在MySQL5.0和更高版本中,Mysql服务器自身实现了DECIMAL的高精度计算。相对而言,CPU直接支持原生浮点计算,所以浮点运算明显更快。
浮点和DECIMAL都可以指定精度。对于DECIMAL列,可以指定小数点前后所云寻得最大位数。这会影响列的空间消耗。MySQL5.0和更高版本将数字打包和保存到一个二进制字符串中(每四个字街存9个数字)。例如:DECIMAL(18,9)小数点左右两边都将存储9个数字,共九个字节:小数点前数字用四个字节,小数点后数字用四个字节,小数点本身一个字节。
在MySQL5.0和更高版本中,DECIMAL最多允许65个数字,而早期的版本中是254个数字,并且保存为未压缩的字符串(每个数字一个字节)。然而并不能在计算中使用这么大的数字,因为DECIMAL只是一种存储格式,在计算中会转化为DOUBLE类型。
3)字符串类型
varchar(变长)、char(定长)、binary、varbinary、blob(二进制方式存储)、text(字符串方式存储)
varchar类型用于存储变长字符串,他必定长更节省空间,因为他仅使用必要的空间。有一种情况例外,如果MySql表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长的存储,这会很浪费空间。
varchar需要使用一个或者两个额外的字节记录字符串的长度:如果列的最大长度小于或等于255字节,则使用一个字节表示。否则使用两个字节。
varchar节省了空间,所以对性能也有帮助。但是,由于行是变长的,在UPDATE时,可能使行变得比原来更长,这就需要做额外的工作。不同存储引擎处理不同。
有如下几个适合使用varchar的情景:
字符串列的最大长度比平均长度大很多;
列的更新很少,所以碎片不是问题。
使用了像UTF-8这样复杂的字符集,每个字符都是用不同的字节数进行存储。
char的类型是定长的,当存储CHAR值时,MySql会删除末尾所有的空格。(在MySql4.1和更老的版本中,varchar也是这样实现。也就是说,在这些版本中,char和varchar在逻辑上是一样的,区别只是在存储格式上)。char值会根据需要采用空格进行填充以方便比较。
适合使用char的情景:
char适合存储很短的字符串,或者所有的值都接近一个长度。
对于经常变更的数据,char也比varchar更好,因为char不容易产生碎片。
对于非常短的咧,char比varchar在存储空间上也更有效率。varchar需要额外字节存储长度。
与char和varchar类似的还有binary和varbinary,他们存储的是二进制字符串。二进制字符串与常规字符串类似,但是二进制字符串存储的是字节码,而不是字符。填充也不一样:MySql填充binary采用的是 (零字节),而不是空格。在检索是也不会去掉填充值。
blob和text都是为了存储很大的数据类型而设计的字符串数据类型。实际上,他们份数量组不同的数据类型家族:字符类型是TINYTEXT、SMALLTEXT、TEXT、MEDIUMTEXT、LONGTEXT,对应的二进制类型是TINYBLOB、SMALLBLOB、BLOB、MEDIUMBLOB、LONGBLOB。BLOB是SMALLBLOB的同义词,TEXT是SMALLTEXT的同义词。
MySql会把每个BLOB和TEXT当做一个独立的对象处理。存储引擎在存储时,通常会做特殊处理。BLOB和TEXT家族之间仅有的不同是:BLOB类型存储的是二进制数据,没有排序规则或者字符集,而TEXT类型有字符集和排序规则。
4)日期和时间类型
DATETIME、TIMESTAMP
MySql能存储的最小时间粒度为秒(MariaDB支持微妙级别的时间类型)。但是MySql可以使用微秒级的粒度进行临时运算。
DATETIME,精度秒,8字节存储空间,范围1001年~9999年,值与时区无关。
TIMESTAMP,显示的值依赖于时区,4字节存储空间,存储范围1970年~2038年,插入时未指定值,则默认为当前时间。MySql提供FROM_UNIXTOME()将UNIX时间戳转化为日期, UNIX_TIMESTAMP()将日期转化为UNIX时间戳。
除了特殊行为之外,应该尽可能使用TIMESTAMP类型,因为它比DATETIME空间效率更高。有时候会将UNIX时间戳存储为整数值,这不会带来任何收益。用整数存储时间戳的格式通常不方便处理。
如果要存储比秒更小的粒度,可以使用BIGINT存储微秒级别的时间戳,或者使用DOUBLE存储秒之后的小数部分。也可以使用MariaDB代替MySql。
5)特殊数据类型
某些类型的数据并不直接与内置的类型一致。地狱喵机精度的时间戳就是一个例子。另一个例子是IPv4地址,经常使用varchar(15)来存储IP地址,然而,它实际上是32位无符号整数,不是字符串。小数点讲地址分成四段的表示方法只是为了让人们容易阅读。所以应该使用无符号整数来存储IP地址。MySql提供了INET_ATON()和INET_NTOA()函数在这两种表示方法之间进行转换。