MySQL应用技术4 — 数据类型选择

MySQL应用技术1 — MySQL架构简介
MySQL应用技术2 — 事务简介
MySQL应用技术3 — MVCC
MySQL应用技术5 — 约束与范式
MySQL应用技术6 — 数据库中的锁
MySQL应用技术7 — 性能优化简析


良好的逻辑设计和物理设计是高性能的基石,应该根据系统要执行的查询语句来设计表和库,这往往需要权衡各种因素。比如说使用反范式的设计可以加快某些类型的查询,从而避免连表。但同时却也增加数据存储的空间。因此我们从以下n个方面来作为库表设计的原则。

选择优化的数据类型

选择优化的数据类型通常要遵循以下三个原则
1. 更小的通常更好
一般情况下,应该尽量使用可以正确存储数据的最小数据类型(比如只需要存0-200 则使用tinyint unsigned)。更小的数据类型通常更快,因为他们占用更少的磁盘、内存和cpu缓存,并且处理时需要的CPU周期也更少。
2. 简单就好
简单数据类型通常需要更少的CPU周期,比如整形比字符型操作代价更低。有两个例子
1、应当使用MySQL内建的类型(date,time,datatime)而不是字符串来存储时间。
2、应该使用整形存储ip地址
3. 尽量避免Null
如果查询的列中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值的比较都比较复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。当可为NULL的列被索引时,每个索引记录需要一个额外的字节。(InnoDB中使用单独的位(bit)来存储NULL值,所以对于很多值为NULL,只有少数行的列有非NULL的情况具有很好的空间效率)

一般项目开发中,数据库中常设计到类型有 数值型、字符串型、日期型 这三种。下面来分别讨论下该如何使用

数值型
一般来说有两种数值型的数字 整数 和 实数。对于整数的存储,可以根据范围的不同选择以下类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别使用8,16,24,32,64位存储空间。他们可以存储的数值范围从-2的N-1次方2的N-1次方-1,其中N是存储空间的位数。如果加上UNSIGNED属性,表示不允许复制,这大致可以使整数的上线范围提高一倍。而对于实数类型,在开发中一般不建议使用,因为浮点型一定会丢精度(DECIMAL不是浮点型,是精确类型)。对于一般数值型问题,比如说计算金钱等。一般是先将数值乘以精确度允许范围后(比如说要精确到小数点后5位,那么就先乘100000),以整数类型存储。顺便一提INT(1)这样的写法毫无意义,底层存储一样,只是交互工具可能会进行截取。

字符串类型
一般来说我们使用的字符串是VARCHAR和CHAR类型,其在磁盘和内存中的存储一般跟存储引擎的具体实现有关,我们还是主要来看我们常用InnoDB。
VARCHAR类型用于存储可变长字符串,是最常见的字符串存储类型,它比固定长度类型(char)占用更少存储空间(除了使用ROW_FORMAT=FIXED创建的表),只使用必要的空间。VARCHAR节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,在UPDATE时可能使行变得比原来更长,这就需要做额外的工作。如果一个行占用的空间增长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理方式也不一样:MyISAM会将行拆成不同的片存储,InnoDB则需要分裂也来使行可以放进页内。所以VARCHAR适合于
- 最大长度远大于平均长度;
- 很少发生更新的时,碎片不是问题;
- 使用了想UTF-8这样复杂的的字符集,每个字符都是用不同的字节数进存储
(5.0以上版本,取值或设置值都会保存字符串末尾的空格,4.1之前的版本都会把字符串末尾的空格删除掉。)

CHAR类型是定长的,MySQL总是根据定义的字符串长度分配足够的空间。当存储CHAR值时,MySQL会删除所有末尾的空格(实在MySQL服务器做的,更存储引擎无关)。适用于:
- 密码的MD5值(因为是定长的)
至于说其他的如BLOB或者TEXT等类型,建议存储Mongo、ES、文件服务器中,方便做全文检索,及文件转化。

时间类型
DATETIME类型能存储1001年到9999年,精度为秒。它把时间类型封装到格式为YYYYMMDDHHmmSS的整数中,与时区无关。使用8个字节的存储空间。
TIMESTAMP类型则如其名字,保存了从1970年1月1日午夜以来的秒数,它和UNIX时间戳相同。它只占用了4个字节的存储空间,因此只能表示到2038年(完了,那时候还退休不了,咋整啊)。它可以显示的设置默认值为当前时间或当行发生更新时,把值更新为当前时间。
如果需要存储比秒更精确的时间粒度,推荐使用BIGINT类型存储纳秒级的时间戳。

你可能感兴趣的:(MySQL应用技术4 — 数据类型选择)