← 返回题目列表

字典表和枚举字段在数据库中如何设计?什么时候应该建表?

中等 第 29 / 33 题 更新于 2026/07/30
字典表枚举表设计

简化版

固定且很少变化的取值可以用枚举字段或代码常量;需要运营配置、展示文案、多语言、排序、启停、扩展属性或跨系统共享时,应该设计字典表。面试回答要强调:字典表不是把所有枚举都数据库化,而是给“会变化、要治理、要展示”的业务取值一个可维护入口。

详细版

枚举字段适合状态少、语义稳定、强依赖代码逻辑的场景,比如订单状态、支付状态。这类值通常要参与状态机和业务分支,随便在数据库加一项反而危险。

字典表适合“取值本身是业务配置”的场景,比如证件类型、行业分类、渠道来源、门店标签、风险等级展示文案。常见字段包括 dict_typecodenamesort_noenabledremark

设计时要注意唯一约束、缓存策略、启停语义和历史数据兼容。字典项下线不代表历史记录失效,因此通常不要物理删除,而是用启停字段控制新增选择。

完整版教学

一、先区分“业务状态”和“展示配置”

很多人看到字段有几个固定值,就想建字典表;也有人把所有取值都写死在代码里。这两种都太极端。关键要看这个取值到底是业务状态,还是展示和配置。

订单状态 CREATED/PAID/SHIPPED/CLOSED 通常是业务状态。它会影响流程流转、权限、库存和资金处理,不应该让运营在后台随便新增一个状态。

而“客户来源:官网、抖音、地推、转介绍”更多是配置和统计口径,后续可能新增渠道、调整展示名、排序或禁用,这类更适合字典表。

二、字典表的基本结构

一个常见字典表可以这样设计:

CREATE TABLE sys_dict_item (
  id BIGINT PRIMARY KEY,
  dict_type VARCHAR(64) NOT NULL,
  code VARCHAR(64) NOT NULL,
  name VARCHAR(128) NOT NULL,
  sort_no INT NOT NULL DEFAULT 0,
  enabled TINYINT NOT NULL DEFAULT 1,
  remark VARCHAR(255),
  UNIQUE KEY uk_type_code (dict_type, code)
);

dict_type 表示一组字典,例如 customer_sourcecode 是稳定存储值;name 是展示文案。业务表里通常存 code,不要存 name,否则文案改名会污染历史语义。

三、为什么唯一约束很关键

字典表最怕同一个类型下出现两个相同 code。代码读取时到底用哪一个,会变成不确定行为。

例如 customer_source + douyin 如果重复插入两条,统计报表、下拉选择、缓存加载都可能出现重复项。因此 (dict_type, code) 必须有唯一索引。

字段是否稳定用途
code稳定入库、接口、统计
name可变页面展示
sort_no可变下拉排序
enabled可变控制是否可选

这个表能帮助面试官看到你知道“存储值”和“展示值”要分离。

四、启停和删除要谨慎

字典项不用了,通常先禁用,不要物理删除。因为历史业务数据还可能引用旧 code,报表和详情页仍需要解释它。

假设客户表里有 100 万条 source='offline_2024' 的历史数据。如果你直接删除字典项,页面展示时就只能显示原始 code,用户体验和报表解释都会变差。

更稳的做法是 enabled=0 后不允许新建业务选择,但历史数据仍能展示名称。

五、字典表要不要缓存

字典数据通常读多写少,非常适合缓存。可以在应用启动时加载,也可以用 Redis 缓存 dict_type -> items

但缓存要有刷新机制。后台修改字典后,可以发送配置变更事件,或设置较长 TTL 加主动删除。不能让运营改了渠道名,线上页面半天不生效。

如果字典参与核心判断,缓存刷新更要谨慎,必要时发布流程和字典变更要有审批。

六、常见误区与追问

  • 误区:所有枚举都应该建字典表。 强业务状态更适合代码枚举和状态机保护,随意数据库化会破坏流程约束。
  • 误区:业务表直接存字典名称更方便。 名称会变,应该存稳定 code,展示时再翻译。
  • 误区:字典项不用了直接删除。 历史数据仍可能引用它,禁用通常比删除安全。
  • 追问:字典表唯一约束怎么建? 通常用 (dict_type, code) 唯一约束,保证同一组内 code 不重复。
  • 追问:字典缓存怎么刷新? 可用主动失效、配置事件或短 TTL,关键是变更后有可控传播路径。

七、加强记忆

记忆钩子:枚举像代码里的交通规则,字典表像路牌和下拉选项;规则不能让人随便改,路牌需要可配置、可展示、可下线。

回答这题时先划边界,再给表结构和约束,最后补启停、历史兼容和缓存刷新。这样能避免把字典表讲成“简单 key-value 表”的浅层答案。