MySQL支持的数据类型很多,选择正确的数据类型对于高性能至关重要。下面几个简单的原则都有助于做出更好的选择。

  • 更小的通常更好

应该尽量使用可以正确储存数据的最小数据类型。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。如果无法确定哪个数据类型时最好的,就选择你认为不会超过范围的最小类型。

  • 简单就好

简单数据类型的操作通常需要更少的CPU周期。例如,整形比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整形更复杂。比如用MySQ内建的类型而不是使用字符串来存储日期和时间、应该用整形存储IP地址。

  • 尽量避免null

如果查询中包含可为null的列,对MySQL来说更难优化,因为可为null的列使得索引、索引统计和值比较都较为复杂。可为null的列会使用更多的存储空间,在MySQL里也需要特殊处理。当可为null当列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引变成可变大小的索引。

通常把可为null的列改为not null带来的性能提升比较小,所以没有必要在现有的架构中查找并修改这种情况,除非确定这回导致问题。

例外的是在InnoDB使用独立的位存储null值,所以对于稀疏数据(很多值为null,只有少数行的列有非null值)有很好的空间效率,但这一点不适用于MyISAM。

在为列选择数据类型时。

第一步需要确定合适的大类型:数字、字符串、时间等
第二步是选择具体类型。MySQL的很多数据类型都可以存储相同类型的数据,只是存储的长度和范围不一样、允许的精度不一样,或者需要的物理空间不同。

整数类型

存储整数可以用这几种类型

类型 存储位数
tinyint 8
smallint 16
mediumint 24
int 32
bigint 64

它们可以存储的值的范围-2^(N-1)^到2^(N-1)^-1,其中N是存储空间的位数。
整数类型还有可选有符号属性,表示不允许负值,这可以使正数的上限提高一倍。如tinyint无符号可以存储的范围是0到255,但他允许负值但存储范围是-128到127。

MySQL选择不同的整数类型是决定怎么在内存和磁盘中保存数据的。但是在整数计算一般使用64位但bigint整数,即使32位环境也是一样。(除了聚合函数)

MySQL还可以为整数类型指定宽度。如int(11),但是它不会限制值的合法范围,只是规定了MySQL的一些交互工具(如SQLyog,navicat)用来显示字符的个数。对于存储和计算来说,int(1)和int(11)是相同的。

实数类型

实数是带有小数部分的类型。MySQL中可以用decimal、float和double来存储实数类型。

float和double类型支持使用标准的浮点运算进行近似计算。
decimal类型用于存储精确的小数,在MySQL5.0以及更高的版本中,MySQL服务器自身实现了decimal的高精度计算。

浮点类型在存储同样范围的值时,通常比decimal使用更少的空间。float使用4个字节存储,double使用8个字节存储,相比flaot有更高的精度和更大的范围。在浮点计算时,MySQL都使用的double作为内部浮点计算的类型。

在考虑对小数进行精确计算时,使用decimal(如财务数据),但在数据量大时,可以考虑使用bigint代替decimal,将需要存储但货币单位根据小数的位数乘以相同的倍数存储。这样可以避免decimal精确计算代价高的问题。

float和double使用的是cpu支持的原生浮点计算,所以快。
decimal是MySQL服务器自身实现的高精度计算。

字符串类型

varchar和char是两种最主要的字符串类型。

varchar

varchar类型用于存储可变长字符串,是最常见的字符串数据类型。它比定长类型更节省空间,因为它仅使用必要的空间。

varchar需要使用1个或2个额外字节记录字符串长度:如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用2个字节。

varchar节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,在update时可能使行变得比原来更长,这就导致需要做额外的工作。因为行占用的空间增长,并且在页内没有更多的空间可以存储。这种情况下,MyISAM会将行拆成不同的片段存储,InnoDB需要分裂页来使行可以放进页内。其他一些存储引擎也许不在原数据位置更新数据。

使用varchar最合适的场景是:在字符串列的最大长度比平均长度大很多;列更新很少(碎片不是问题);使用了像utf-8这样复杂的字符集,每个字符都使用不同的字节数进行存储。

使用varchar(5)和varchar(200)存储‘hello'的空间开销是一样的,但是使用更长的列会消耗更多的内存,MySQL通常会分配固定大小的内存快来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕,在利用磁盘临时表进行排序同样糟糕。所以最好的策略是只分配真正需要的空间。

char

char类型是定长的。MySQL总是根据定义的字符串长度分配足够的空间。当存储char值时,MySQL会删除所有的末尾空格。char值会根据需要采用空格进行填充以方便比较。

char适合存储很短的字符串,或者所有值都接近同一个长度。例如密码的MD5值。对于经常变更的数据,char也比varchar更好,因为定长的char不容易产生碎片。对于非常短的列,char比varchar在存储空间上也更有效率,因为varchar需要额外字节记录长度。

更多相关文章

  1. Android需要的java基础
  2. Android项目流程、设计原则、编码规范、技术特点和过时技术
  3. 【Android(安卓)电量优化】电量优化 ( Battery Historian 环境要
  4. Android团队如何进行情感设计
  5. Android(安卓)Market中产品图标设计原则
  6. android客户端与服务器数据交换原则
  7. Android开发 数据库操作
  8. android中的数据库操作
  9. Android的NDK开发(3)————JNI数据类型的详解

随机推荐

  1. 2011.07.06——— android 安装apiDemos
  2. Android Talker(1)MAC Environment
  3. Android获取OAID设备标识
  4. Android 获取imei号码,获取手机型号和系统
  5. Android消息机制之三---Message
  6. Android 多国语言文件夹
  7. Android 设置让EditText不自动获取焦点
  8. Android Studio添加aar依赖的两种方式
  9. Android PureMVC
  10. Android Gradle Plugin指南(三)——依赖关