概述
选择更小的数据类型:一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。但是要确保没有低估需要存储的值的范围
尽量选择简单的数据类型:简单数据类型的操作通常需要更少的CPU周期,例如整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂(eg:存储日期和时间应该使用MYSQL内建的类型(date,time,datetime)而不是字符串;存储IP地址应该用整型)
尽量避免NULL:通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。如果查询中包含可为NULL的列,对MYSQL来说更难优化可为NULL的列使得索引、索引统计和值比较都更为复杂
可为NULL的列会使用更多的存储空间,在MYSQL里也需要特殊处理
当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引
(通常把可为NULL的列改完NOT NULL带来的性能提升比较小,所以调优时没有必要首先在现有schema中查找并修改掉这种情况,除非确定这会导致问题,但是如果计划在列上建索引,就应该尽量避免设计成可为NULL的列。当然也有例外,例如值得一提的是,InnoDB使用单独的位存储NULL值,所以对于稀疏数据(即很多值为NULL,只有少数行的列有非NULL值)有很好的空间效率,但这一点不适用于MyISAM)
数据类型:
整数类型:
整数类型分为两种:整数和实数。整数类型分为:TINYINT(8位存储空间),SMALLINT(16位存储空间),MEDIUMINT(24位存储空间),INT(32位存储空间),BIGINT(64位存储空间),存储的值的范围
到
,N为存储空间的位数。可选UNSIGNED属性,表示不允许负值,大致可使证书的上限提高一倍,有符号和无符号类型使用相同的存储空间,并具有相同的性能。MYSQL可以为整数类型指定宽度,例如INT(11),对于大多数应用这是没有意义的,它不会限制值的合法范围,只是规定了MYSQL的一些交互工具,如MYSQL命名行客户端用来显示字符的个数,对于存储和计算来说,INT(1)和INT(20)是相同的。
实数是带有小数部分的数字。但不只是用于存储小数部分,可以使用DECIMAL存储比BIGINT还大的整数。MYSQL既支持精确类型,也支持不精确类型。 DECIMAL只是一种存储格式,在计算中DECIMAL会转为DOUBLE类型。有多种方法可以指定浮点列所需要的精度,这会使得MYSQL悄悄选择不同的数据类型,或者在存储时对值进行取舍。这些精度定义是非标准的,所以最好只指定数据类型不指定精度。
字符串类型:
VARCHAR类型用于存储可变长字符串,比定长类型更节省空间(如果MYSQL表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储,这会很浪费空间)VARCHAR需要使用1或2个额外字节记录字符串的的长度:如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用2个字节。VARCHAR节省存储空间,但是在UPDATE时可能使行变得比原来更长,导致需要做额外的工作。1.字符串列的最大长度比平均长度大很多;2.猎德更新很少,碎片不是问题;3.使用了像UTF-8这样复杂的字符集,每个字符都是用不同的字节数进行存储时;以上3种情况适合是用VARCHAR。(使用VARCHAR(5)和VARCHAR(200)存储'hello'的空间开销是一样的,但是更长的列会消耗更多的内存,因为MYSQL通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕;在利用磁盘临时表进行排序时也同样糟糕,所以最好的策略是只分配真正需要的空间)
CHAR类型是定长的,适合存储很短的字符串,或者所有值都接近一个长度的数据。例如,CHAR非常适合存储密码的MD5值,因为这是一个定长的值。对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。存储CHAR值时,MYSQL会删除所有的末尾空格。
BLOB和TEXT类型
BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。BLOB是SMALLBLOB的同义词,TEXT是SMALLTEXT的同义词(字符型包含:TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;对应的二进制类型:TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB)BLOB与TEXT的不同:BLOB类型存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集和排序规则。MYSQL对BLOB和TEXT列进行排序与其他类型不同,只对每列的最前max_sort_length字节而不是整个字符串做排序。如果只需要排序前面一小部分字符,则可以减小max_sort_legth的配置。或者使用ORDER BY SUSTRING(column,length)
ENUM枚举类型
有时候可以使用枚举列代替常用的字符串类型,枚举列可以把一些不重复的字符串存储成一个预定义的集合,MYSQL在存储枚举时非常紧凑,会根据列表的数量压缩到一个或两个字节中。MYSQL在内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”映射关系的“查找表”
CREATE TABLE enum_test( e ENUM('fish','apple','dog') NOT NULL);
INSERT INTO enum_test(e) VALUES('fish'),('dog'),('apple');
以上三行数据实际存储为整数,而不是字符串,如果使用数字作为ENUM枚举常量,这种双重性很容易导致混乱,例如ENUM('1','2','3')应尽量避免这么做。另外,枚举字段是按照内部存储的整数而不是定义的字符串进行排序的(即,以上数据按照 'fish','apple','dog'的顺序进行排序),所以定义枚举列时,应按照需要的顺序来定义,或者在查询中使用FIELD()函数显式地指定排序顺序,但是会导致MYSQL无法利用索引消除排序。
枚举的缺点:字符串列表是固定的,添加或删除字符串必须使用ALTER TABLE,因此对于一系列未来可能会改变的字符串,使用枚举不是一个好主意,除非能接受只在列表末尾添加元素。由于MYSQL把每个枚举值保存为整数,并且必须进行查找才能转换为字符串,所以枚举列有一些开销。通常枚举的列表都比较小,所以开销还可以控制,但也不能保证一直如此。在特定情况下,把CHAR/VARCHAR列与枚举列进行关联可能会比直接关联CHAR/VARCHAR列更慢。
日期和时间类型
日期类型分为:DATETIME和TIMESTAMP。
DATETIME类型能保存大范围的值,从1001年到9999年,精度为妙。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关,使用8个字节的存储空间。
TIMESTAMP类型保存了从1970年1月1日午夜(格林尼治标准时间)以来的秒数,它和UNIX时间戳相同。TIMESTAMP只使用4个存储空间,因此它的范围比DATETIME小得多:只能表示1970年到2038年。如果在多个时区存储或访问数据,TIMESTAMP和DATETIME的行为将很不一样,TIMESTAMP提供的值与时区有关系,后者则保留文本表示的日期和时间。例如,存储值为0的TIMESTAMP在美国东部时区显示为“1969-12-31 19:00:00”与格林尼治时间差5个小时。TIMESTAMP列默认为NOT NULL。
位数据类型
BIT:MYSQL5.0之前,BIT是TINYINT的同义词,5.0之后二者为两种不同的数据类型。BIT列的最大长度是64位。MYSQL把BIT当作字符串类型,而不是数字类型。
mysql5.7版本中,当检索BIT(1)的值时,结果是一个包含二进制0或1值的字符串,而不是ASCII码的“0”或“1”
8.0.11版本中
SET:如果需要保持很多true/false值,可以考虑合并这些列到一个SET数据类型,它在MYSQL内部是以一系列打包的位的集合来表示的,可以有效利用存储空间。主要缺点是改变列定义的代价较高,需要用ALTER TABLE,改变大表开销过大。一般来说也无法在SET列上通过索引查找。
最后
以上就是高兴柠檬为你收集整理的mysql数据库选择数据类型_mysql数据库——选择优化的数据类型的全部内容,希望文章能够帮你解决mysql数据库选择数据类型_mysql数据库——选择优化的数据类型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复