用 int 更合适,因其在数据库层面更高效、语义更清晰且变更成本低;varchar 适用于自然语言关键词、频繁变动或跨系统依赖字符串字面量的场景。

用 int 更合适,前提是枚举值稳定、数量少、有明确业务含义且不对外暴露原始值。
为什么 int 通常是更好选择
数据库层面更高效:int 比 varchar 占用空间小(通常 4 字节 vs 不定长)、索引更快、JOIN 和 WHERE 查询性能更高;
语义更清晰:配合注释或字典表,能明确表达状态含义(如 status=1 表示“待审核”,2 表示“已通过”);
变更成本低:如果只是调整文字描述(比如把“已通过”改成“审核通过”),只需改字典表或应用层映射,无需动数据和结构。
varchar 适合这些情况
枚举值本身是自然语言关键词,且会被直接用于查询或展示(如 country_code='CN'、payment_method='alipay');
值可能频繁增删,且无法预估范围(如用户自定义标签);
需要跨系统共享含义,且对方系统依赖字符串字面量(如对接第三方 API 要求传 'active' 而非 1);
团队明确约定“枚举即字符串”,并统一管理(如用 CHECK 约束 + 应用层常量类)。
实用建议
- 优先用 tinyint 或 smallint(根据取值范围选),比 int 更省空间
- 加 CHECK 约束限制合法值(如
CHECK (status IN (0,1,2))),避免脏数据 - 在建表注释或单独字典表中说明每个数字对应的状态名,方便维护
- 应用层别硬编码数字,用常量或枚举类封装(如
Status.PENDING = 0) - 如果后期发现 varchar 更合适,可通过添加计算列或视图平滑过渡,不必立刻迁移历史数据
一个常见误区
认为 “varchar 可读性强所以更安全”——其实可读性应由应用层或视图解决,不是把数据存成字符串的理由。数据库里存 int + 外键/字典表,反而更规范、更可控。










