固定员工类型存储选Java Enum还是数据库参考表更合适?
方案对比与问题解答
核心思路建议
首先你提到员工类型不会频繁变动,其实没必要二选一,两种方案结合使用是最优解,兼顾代码的类型安全性和数据库的完整性约束:
- 数据库保留
worker_type参考表:用于外键关联worker表的worker_type_id字段,避免worker表出现无效的类型id脏数据 - 代码中保留
WorkerType枚举:枚举值的id属性和worker_type表的worker_type_id一一对应,所有业务逻辑判断、查询条件都基于枚举的固定id,仅用参考表的worker_type_label做前端展示使用
具体问题解答
1. 采用参考表方案如何查询所有全职员工?
你给出的SQL写法本身就不合理,完全不应该依赖worker_type_label做查询条件,正确的写法有两种:
- 不需要返回类型名称的场景,不需要关联查询:
select * from worker where worker_type_id = 1
- 需要返回类型名称的场景,过滤条件依旧用固定id:
select w.*, wt.worker_type_label from worker w left join worker_type wt on w.worker_type_id = wt.worker_type_id where wt.worker_type_id = 1
代码中可以直接用枚举的id值拼接条件,比如Java中用WorkerType.FULL_TIME.getId()获取对应id传入SQL,不需要硬编码字符串。
2. 如何避免修改参考表label导致代码报错?
只要遵循以下规则就可以完全避免这个问题:
- 代码中所有逻辑判断、查询条件永远不依赖
worker_type_label字段,该字段仅做前端展示使用 - 参考表的
worker_type_id是永不变更的固定值,和代码枚举的id一一对应 - 给
worker_type参考表设置严格的权限控制,仅授权少数管理员可修改,修改前必须走变更评审,禁止随意修改id值 - 增加启动校验逻辑:项目启动时自动校验代码中
WorkerType枚举的所有id、名称和数据库worker_type表的记录是否一致,不一致直接启动失败,提前暴露不一致问题
额外补充:为什么很多人推荐参考表方案?
相比纯枚举方案,参考表有两个不可替代的优势:
- 多语言/多服务共用类型的场景,不需要每个服务都单独维护一套枚举,避免不同服务枚举值不一致的问题
- 数据库直接查询统计的场景更方便,不需要记id对应的类型含义,关联参考表就可以直接得到可读的统计结果
内容的提问来源于stack exchange,提问作者Murtaza Hasan
相关产品推荐
相关产品推荐

