同样写成 0012,为什么商品编码适合用字符串,购买数量却适合用整数?编码要保留原来的字符,数量要参与计算;金额还要保留精确的小数,生日和下单时间则要区分是否需要时分秒。数据类型规定一个字段保存哪一类值,以及这些值的长度、精度或日期形式。选类型,先看字段表示什么,再看它需要容纳哪些值。

从字段声明和 Type 列读懂类型

表中的一列也叫一个字段。在 MySQL 的列声明中,字段名后面跟着类型。例如这些声明片段:

quantity    INT,
unit_price  DECIMAL(8,2),
customer_name VARCHAR(20),
birthday    DATE,
ordered_at  DATETIME

quantity 是字段名,INT 是类型;unit_price 是字段名,DECIMAL(8,2) 是带参数的类型声明。查看已有表的 DESCRIBE 结果时,Field 列对应字段名,Type 列对应类型,常见形式包括 int、decimal(8,2)、varchar(20)、date 和 datetime。

不同字段可以先按用途区分:

字段表示什么 值的例子 常用类型选择
商品数量 12 件 INT:整数
商品单价 19.90 元 DECIMAL(8,2):精确小数
允许误差的测量值 温度测量结果 FLOAT / DOUBLE:近似数值
姓名或编码 '张小明'、'0012' CHAR / VARCHAR:字符串
出生日期 '2000-02-29' DATE:日期
下单时刻 '2026-11-10 09:15:00' DATETIME:日期和时间

数值:数量、金额和近似测量值

购买 12 件商品,数量没有小数部分,可以用 INT。单价 19.90 元需要小数,结算又通常要求精确到分,可以用 DECIMAL。整数和精确小数都属于精确数值类型;FLOAT、DOUBLE 则保存近似数值。有没有小数点,与是不是近似值,是两个不同问题。 DECIMAL 有小数部分,也能保存精确值。

DECIMAL(8,2) 里的两个参数分别约束什么?8 是精度,表示总有效位数;2 是小数位数,表示小数点后的位数。因此,小数点前最多有 8 - 2 = 6 位。小数点和正负号不占这 8 个数字位。

理解这个位数限制,可以想象一张有 8 个数字填写格的纸质表单:最后 2 格固定留给小数部分,整数部分就只剩前面 6 格,不能再单独占用 8 格。

Mermaid 图 1

123456.78 恰好用满 6 个整数位和 2 个小数位,可以表示;1234567.89 有 7 个整数位,再加 2 个小数位,总计 9 位,超过了 DECIMAL(8,2) 的容量。把 8 理解成“整数部分可以有 8 位”,就会错误地认为后一个值也放得下。

金额示例优先选 DECIMAL,是因为需要按十进制小数精确保存。FLOAT、DOUBLE 用近似值表示数值,有些十进制小数不能原样精确表示;把它们当成精确值比较,可能出现差异。对于允许误差的测量值,近似类型可以是合理选择。

字符串:编码要保留原样,长度按字符计数

商品编码 '0012' 和数量 12 看起来相似,含义却不同。编码中的两个前导零属于编号形式;若用整数保存,数值就是 12,不会保留“写成四位”的原样。数量要参与加减,适合数值类型;编码主要用于识别商品,适合字符串。姓名 '张小明' 也属于字符串,不能因为某个字段里恰好全是数字字符,就直接选择整数。

CHAR(n) 是定长字符串,VARCHAR(n) 是变长字符串。比如固定 6 个字符的代码可以考虑 CHAR(6);长度不一的姓名可以考虑 VARCHAR(20)。CHAR 存储时会在右侧补空格到声明长度,VARCHAR 按实际字符串长度保存,不补齐到 n。这里的 n 表示最大字符数,不是每个值都必须输入 n 个字符。

VARCHAR(20) 中的 20,也不是“最多 20 字节”。'张小明' 是 3 个字符,'ABC12' 是 5 个字符,二者都没有超过 20。字符是文本中的单位,字节是存储大小的单位;在 utf8mb4 字符集下,不能把中文字符和英文字符一律按相同字节数计算。

Mermaid 图 2

所以,理解 VARCHAR 要区分字符数量和存储字节限制:n 按字符声明,但实际允许的最大长度还受字符集和整行共享的 65,535 字节限制影响。VARCHAR 没有通用的“最多 255 个字符”上限;也不能反过来认为,无论一行还有多少其他字段,单个 VARCHAR 总能装下 65,535 个字符。

这就像共用一个书架时,规定某一组书最多放 20 本,并不等于为它预留了足够放下任意 20 本书的空间:书有薄有厚,其他组也要占地方。书的本数对应字符数,占用的空间对应字节数;字符数量上限和共享空间限制需要同时满足。

日期与时间:生日和下单时刻需要不同类型

生日只要知道哪一天,可以用 DATE;下单时刻需要知道几点几分几秒,可以用 DATETIME。例如两笔订单都发生在 2026 年 11 月 10 日,一笔是 09:15:00,另一笔是 18:40:00。只保留日期时,两者都是同一天,无法凭这个字段区分它们在当天的先后;保留日期和时间,才能表达这两个时刻。

类型 保存的部分 常用形式 值的例子
DATE 年、月、日 YYYY-MM-DD '2000-02-29'
DATETIME 年、月、日和时、分、秒 YYYY-MM-DD hh:mm:ss '2026-11-10 09:15:00'

年份写四位,月份、日期、时分秒按示例补足位数,可以避免两位年份带来的世纪歧义。形式对了,还要是有效日期:2000 年是闰年,'2000-02-29' 有效;'2025-02-29' 则不存在,不能当作正常生日值。

日期值常用单引号书写,但加了单引号不代表字段就是字符串类型。'2000-02-29' 可以是提供给 DATE 字段的日期值;'0012' 则可以是提供给字符串字段的商品编码。辨认字段类型,要看列声明或 DESCRIBE 的 Type,再结合字段含义判断:数量需要整数,单价需要精确小数,姓名和编码需要字符串,生日需要日期,下单时刻需要日期和时间。