概述

  • 更小的通常更好,如果只存 0-200,那么 tinyint unsigned 是一个非常不错的选择

注:有符号无符号使用相同的存储空间,并且具有相同的性能。int(10) 和 int(11),存储和计算来说是一样的,只是显示的字符不同。可以考虑使用 bigint 代替 decimal 和 float

  • 越简单越好,比如整型比字符型要好,比如时间采用内置数据类型,而不是自己定义字符串来存,比如存IP,可以用整型而不是字符串

注: DATETIME 和 TIMESAMP 都是时间类型,可 TIMESAMP 比 DATETIME 少一半的存储空间,所以允许的时间范围要小很多。但是会根据时区变化,这个有好也有坏,需要注意

  • 尽量避免 NULL

注:InnoDB 使用单独的位(bit)存储 NULL 值,所以对于稀疏数据,有很好的空间效率,这个不适合 MyISAM。稀疏数据指:大部分值为 NULL,只有少数行的列有非 NULL 的值

varchar 和 char

varchar

比定长会节省空间,但是如果建表时使用了 ROW_FORMAT=FIXED 那么每一行都会使用定长存储,会很浪费空间

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

什么时候使用 varchar 是合适的:

  • 字符串列的最大长度比平均长度大很多;
  • 列更新很少,碎片化不是问题;
  • 使用了 utf8 utf8mb4等这样复杂的字符集

char

什么时候使用 char 是合适的:

  • 定长的,比如 MD5 值等

注:末尾空格会截断的问题

BLOB 和 TEXT

字符类型:TINYTEXT ,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT 二进制类型:TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB

BLOB 和 TEXT 家族之间仅有的不同就是: BLOB:存储的是二进制数据,没有排序规则或字符集 TEXT:存储的是字符数据,有字符集和排序规则

使用枚举代替字符串,我建议最好不用枚举

MySQL 在内部会将每个枚举值在列表中的位置保存为整数,在表文件中保存一个映射关系,所以,可以自己枚举,这样还少了映射表,还有需要注意的是,如果枚举的是 1,2,3 这样的话,那么这种映射表的双重性就很容易导致混乱,尽量不要这样做。排序是按照内部存储的整数来排序的,而不是你定义的字符串来排序的

日期和时间类型

DATETIME

采用8个字节存储空间,能存储从 1001 - 9999 年,与时区无关

TIMESAMP

采用4个字节存储空间,能存储从 1970 - 2038 年,与时区有关 内部保存的是 UNIX 时间戳,可以通过内置函数 FROM_UNIXTIME() 将 Unix 时间戳转换成日期,使用 UNIX_TIMESTAMP 将日期格式转换成时间戳