Mysql 支持的数据类型非常之多,如何选择正确的数据类型对于获得高性能至关重要。下面是几个简单原则,用于帮助选择数据类型。

  1. 更小的通常更好: 应当尽量使用可以储存数据的最小类型,因为其通常占用资源更少。但是不要低估存储值的范围,因为在 schema 中的多个地方增加数据类型的范围是一个非常耗时和痛苦的操作;
  2. 简单就好: 比如应该使用内置类型而不是字符串来存储时间和日期,因为这样操作代价更低。
  3. 尽量避免 NULL: 通常情况下最好指定 NOT NULL,除非真的需要 NULL 值。

在架构的时候首先确定大类型,然后具体到基本类型。

数字类型

mysql 中有两种不同类型的数字,整数和实数。

整数类型

整数类型有:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT。其分别占用 8, 16, 24, 32, 64 位存储空间,值范围为 [-2^(n-1), 2^(n-1)),其中 N 是储存空间位数。

整数类型有可选的 UNSIGNED 属性,表示没有负数。有符号和无符号使用相同储存空间,并有相同性能。另外,mysql 中可以为整数类型指定宽度(int(10)),但是实际上并不会影响到储存和计算。

实数类型

FLOAT 和 DOUBLE 支持使用标准的浮点运算进行近似计算。DECIMAL 类型用于存储精确的小数,其精确计算开销过大,这里不讲。另外,在存储固定位数的小数如金额,可以转换为整数改用 BIGINT 存储,这样可以同时避免浮点数计算不精确和 DECIMAL 精确计算开销大。

字符串类型

VARCHAR 和 CHAR 是最主要的两种字符串类型,具体实现方式与储存引擎有关。下面以 InnoDB 为储存引擎。BLOB 和 TEXT 都是为储存很大的数据而设计的字符串数据类型,分别采用二进制和字符方式进行储存。

VARCHAR

VARCHAR 类型用于储存可变长字符串,是最常见的字符串数据类型,它比定常类型更节省空间。VARCHAR 需要使用1或2个字节用于记录字符串长度,如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用两个字节。需要注意的是由于行是变长的,那么在 UPDATE 或者其他操作过程中使得行变得比原来更长,就会导致额外的工作。所以 VARCHAR 比较实用于字符串列的最大长度比平均长度大得很多;列的更新很少的情况。

CHAR

CHAR 是定长类型,当储存 CHAR 值时,mysql 会删除所有的末尾空格。CHAR 适合储存很短的字符串,或者所有值都接近同一个长度的值。

日期和时间类型

DATETIME 这个类型能保存大范围的值,从 1001 年到 9999 年,精度为秒。它把日期和时间装到格式 YYYYMMDDHHMMSS 的整数中,与时区无关。使用 8 个字节的存储空间。TIMESTAMP 保存了从 1970 年 1 月 1 日午夜以来的描述,它和 UNIX 时间戳相同。TIMESTAMP 只使用4个字节的储存空间。所以其范围比 DATETIME 小得多,只能表示从 1970 年到 2038 年。除特殊行为之外,通常也应该尽量使用 TIMESTAMP ,因为它比 DATETIME 空间效率更高。