字段类型选择原则是够用且最小。数值类优先用unsigned窄类型;金额必用decimal;字符串按长度选char/varchar,慎用text;时间统一用datetime或timestamp;布尔用tinyint(1);枚举依变更频率选enum、tinyint或代码表。

选字段类型不是挑最“大”或最“通用”的,而是找刚好够用、又最省资源的那个。核心就一条:够用且最小。
数值类字段:按范围和精度精准匹配
整数优先选带 UNSIGNED 的窄类型:
- 状态码(0/1/2)、开关、性别:用 TINYINT UNSIGNED(0–255,占1字节)
- 订单数量、商品库存(确定 ≤65535):用 SMALLINT UNSIGNED(2字节)
- 用户ID、订单号(纯数字,≤21亿):用 INT UNSIGNED(4字节),比 BIGINT(8字节)省一半空间
- 金额必须用 DECIMAL(M,D),比如 DECIMAL(12,2) 支持千万级金额+两位小数;禁用 Float/double(精度丢失)和 VARCHAR(无法计算、排序错乱)
字符串字段:固定长用 CHAR,变长用 VARCHAR,慎用 TEXT
别一概设成 VARCHAR(255) 或 VARCHAR(1000):
- 手机号、身份证号、编码类:长度固定,用 CHAR(N)(如 CHAR(11)),查询更快、存储更紧凑
- 用户名、姓名、标题:用 VARCHAR(N),N 设为业务实际最大长度(如姓名 VARCHAR(20),邮箱 VARCHAR(254))
- 文章正文、日志内容等超长文本,且不参与 WHERE/GROUP BY/ORDER BY:才考虑 TEXT;否则一律用 VARCHAR——因为 TEXT 是离行存储,每次读取多一次 I/O
时间与布尔字段:拒绝字符串伪装
时间存成字符串是典型反模式:
- 统一用 DATETIME 或 TIMESTAMP:前者范围宽(1000–9999年)、占8字节;后者范围窄(1970–2038)、占4字节、带时区转换,日志类高频写入可选 TIMESTAMP
- 布尔值不用 BIT(sql Server)或 Boolean(mysql 别名),直接用 TINYINT(1) 存 0/1,语义清晰、兼容性强、索引高效
- 月份汇总字段(如 “2025-03”)可考虑 CHAR(7),比 DATETIME 更轻量且便于分组
枚举与代码类字段:权衡扩展性与效率
固定选项少、几乎不变的场景可直接用原生类型: