MySQL数据类型

最近在练习一个后台小项目,随便规划了几个需求之后开始搭环境(好吧其实就是写了几个页面然后上ThinkPHP),当正儿八经的开始写后台项目的时候才发现,在数据库中该怎么为每个字段选择合适的数据类型呢?然而我连MySQL数据库的每种数据类型的具体作用都不太熟悉,细思极恐,赶紧恶补一番。

<!--more-->

合理的数据库结构和数据类型是高性能数据库的关键,而使用何种数据类型来保存数据并没有强制的规定,这里找到了前辈们总结的一些经验,感谢互联网。 参考资料:

1. 数据类型

在挑选合适的数据类型之前,先看一看MySQL具体的数据类型有什么吧。

1.1. 数字类型

数字类型又可以分为整数类、小数类和数字类。

1.1.1. 数字类

所谓的“数字类”,就是指 DECIMAL 和 NUMERIC,它们是同一种类型(在phpmyadmin中并没有看见NUMERIC),这种类型又叫做定点数,指的是小数的位数固定,整数部分最大为65,小数部分最大为30。实际上这种数据类型是将数字以字符串形式保存,在运算中不会失真,比较适合用于“价格”、“金额”这样对精度要求不高但准确度要求非常高的财务数据字段。

1.1.2. 小数类

小数即为浮点数,包括FLOAT(占4个字节)和DOUBLE(占8个字节)类两种。浮点数的优点在于表达的数值范围十分大,可以表示很小或者很大的数值。缺点是浮点数存在误差问题,需要尽量避免做浮点比较。实际上,平常项目所用到的数据哪里会需要那么大的数值范围呢。

1.1.3. 整数类

实际上数据库用到最多的数据类型就是整数类,根据所占内存大小分为了TINYINT,SMALLINT,MEDIUMINT,INT和BIGINT这几种,分别占1,2,3,4,8个字节。

1.2. 字符串类型

字符串类型又包括了字符和文本。

1.2.1. 字符

CHAR: 指定字节长度,并且在存储时如果完全占据指定内存(即使内容数据实际大小比指定大小要小); VARCHAR:如果并不确定数据的实际长度,只知道他的阈值(即最大长度),则使用可变长度的VARCHAR类型更合适,这会根据数据的长度自动调节变量所占内存大小(为数据长度+1,多余的一个字节用来存储长度);

1.2.2. 长文本

如果需要存储很大字节的字符串(比如博客,新闻等)可以使用TEXT来存储,此外还有TINYTEXT,MEDIUMTEXT,LONGTEXT。

1.2.3. 大数据

如果要在数据库存储二进制内容,比如图片,可以使用BLOB数据类型。

1.2.4. 枚举和集合

ENUM:最多可以定义 65535 种不同的字符串从中做出选择,只能并且必须选择其中一种,占用存储空间是一个或两个字节 SET:最多可以有 64 个成员,可以选择其中的零个到不限定的多个,占用存储空间是一个到八个字节。

1.3. 日期和时间

DATE:如果数据对日期敏感,而对时间没有要求则可以使用DATE类型,需要8个字节 TIME:在某些情况下可能只需要单独关注时间则使用TIME类型,需要8个字节 DATETIME:包含日期和时间,需要8个字节 TIMESTAMP:用来保存时间戳,只需要4个字节,且可以灵活转换为日期时间,因此使用最为频繁,需要注意的时间戳可能受时区影响。

2. 如何选择

2.1. 选择小数据类型

通常情况下,使用占用内存较小的数据类型来存储和读取数据更好:数据类型越小,在磁盘,内存和处理器缓存中占据的空间很小,只需要很小的CPU处理消耗。 然而,必须保证没有低估需存储数据的数值范围,否则就是“捡了芝麻丢了西瓜”,毕竟数据库就是用来存储并读取数据的。

2.2. 避免使用NULL

如果有需要,最好将字段设置为NOT NULL,空值字段的查询是一件很难的事情,因为空值使得索引、索引分析以及数值比较更加复杂,如果确实需要使用NULL,考虑使用0、特殊值或者一个空的字符串来代替更为合适。

2.3. 常见的数据对应的类型

其中有的数据前面已经提到过了,这里再简单总结一下:

  • 定点数字类型尽量只在对小数精确计算时才使用、如存储财务数据
  • 数据量较大时、建议把实数类型转为整数类型,因为浮点数不精确,而定点数的计算代价昂贵
  • 如果没有需要,不必对浮点数进行精度指定
  • 很短的字符串或所有值都接近同一个长度,使用CHAR,如存储密码的MD5值
  • 经常变更的列最好使用CHAR,因为CHAR产生的碎片少
  • 对于Unicode编码的字符集,最好使用VARCHAR
  • 很大的数据,比如BOLB和TEXT最好存储在单独的表中
  • 如果没有意外,最好使用TIMESTAMP来保存时间,占用内存较小