选择数据类型

数据类型选择的原则

更小的通常更好

一般来说,尽量使用能够正确存储和表示数据的最小数据类型。更小的数据类型通常更快,因为它们占用的磁盘、内存和 CPU 缓存的空间更少,并且处理时需要的 CPU 周期也更少

简单为好

简单数据类型的操作通常需要更少的 CPU 周期

例如,整型数据比字符型数据的比较操作代价更低,因为字符集和排序规则(collation)使字符型数据的比较更复杂。

这里有两个例子:

  • 应该将日期和时间存储为 MySQL 的内置类型而不是字符串类型;

  • 应该用整型数据存储 IP 地址。

IPv4 地址的存储(无符号整数)

人们通常使用 VARCHAR(15) 列来存储 IP 地址。然而,IP 地址实际上是 32 位无符号整数,而不是字符串。用小数点将地址分成四段的表示方法只是为了让人们阅读容易,所以应该将 IP 地址存储为无符号整数

MySQL 提供了 INET_ATON() INET_NTOA() 函数来在这两种表示形式(整数和字符串)之间进行转换。使用的空间从 VARCHAR(15) 的约 16 字节缩减到无符号 32 位整数的 4 字节。

如果担心数据库的可读性,不想继续使用函数查看行数据,可以使用视图来简化数据查看的复杂性。

-- 准备数据
CREATE TABLE ip_test(
    ip INT UNSIGNED
);
INSERT INTO ip_test VALUES (INET_ATON("192.168.10.110"));

-- 查询
SELECT INET_NTOA(ip) FROM ip_test;
+--------------+
|INET_NTOA(ip) |
+--------------+
|192.168.10.110|
+--------------+

尽量避免存储 NULL

即使应用程序本身并不需要存储 NULL(缺失值),很多表也包含可为 NULL 的列,这是因为可为 NULL 是列的默认属性。通常情况下最好指定列为 NOT NULL,除非明确需要存储 NULL 值

如果查询中包含可为 NULL 的列,对 MySQL 来说更难优化,因为可为 NULL 的列使得索引、索引统计和值比较都更复杂。可为 NULL 的列会使用更多的存储空间,在 MySQL 里也需要特殊处理

通常把可为 NULL 的列改为 NOT NULL 带来的性能提升比较小,所以(调优时)没有必要首先在现有 schema 中查找并修改这种情况,除非确定这会导致问题。

数据类型选择的步骤

1. 确定合适的大类型

在为列选择数据类型时,第一步需要确定合适的大类型:数字、字符串、时间等。

2. 选择具体类型

下一步是选择具体类型。很多 MySQL 数据类型可以存储相同类型的数据,但在存储的值范围表示的精度或者需要的物理空间(磁盘和内存)上存在着差异。相同大类型的不同子数据类型有时也有一些特殊的行为和属性

例如,DATETIME 和 TIMESAMP 列可以存储相同类型的数据:时间和日期,精确到秒。然而 TIMESTAMP 只使用 DATETIME 一半的存储空间,还会根据时区变化,而且具有特殊的自动更新能力。另一方面,TIMESTAMP 允许的时间范围要小得多,有时候它的特殊能力会成为障碍。

最后更新于