mysql如何设计简易的审批系统_mysql流程审批管理

2次阅读

用tinyint存状态码(0=待审、1=通过、2=拒绝、3=撤回),配comment说明;分设status与current_step字段支持多级审批;加can_rollback标记和approval_log表保障回退安全;建联合索引idx_pending(status, current_step, approver_id)优化查询。

mysql如何设计简易的审批系统_mysql流程审批管理

审批状态字段怎么建才不踩坑

直接用 TINYINT 存状态码(比如 0=待审、1=通过、2=拒绝、3=撤回),别用字符串或枚举。字符串查起来慢,枚举改起来疼;后期加状态时还得改表结构,ALTER table 锁表风险高。

  • 状态值必须有明确业务含义,写进注释里,比如:COMMENT '0:pending,1:approved,2:rejected,3:withdrawn'
  • 避免用负数或超大整数当状态码,mysqlTINYINT 范围是 -128~127,够用但别越界
  • 别把「审批人」和「状态」混在一个字段里——状态是流程节点,人是执行者,分开放才好查、好审计

如何用单张表支撑多级审批(如部门→总监→VP)

靠一个 step_order 字段 + 状态流转控制,而不是为每级审批建一张表。多表意味着 JOIN 多、事务难控、历史记录散落。

  • 在审批主表加 current_step TINYINT default 0,表示当前卡在哪一级(0=未开始,1=部门审批中,2=总监审批中…)
  • 每次审批动作只更新本 step 的状态和操作人,同时检查 current_step 是否匹配预期,防止跳步或重复提交
  • 用触发器或应用层逻辑保证:只有上一级 status = 1(通过)后,current_step 才能自增;任一级拒绝就直接置 current_step = -1 表示终结

审批驳回后想退回上一步,怎么安全实现

不能简单把 current_step 减 1 —— 上一级可能已归档、审批人已离职、或该步骤本身不允许回退。得靠「可回退标记」+ 显式记录路径。

  • 加一个 can_rollback Boolean DEFAULT FALSE 字段,每次进入新 step 前由业务规则决定是否允许退回(比如总监级驳回可退给部门,但 VP 驳回不可退)
  • 用单独的 approval_log 表存每步操作,含 step_idoperator_idaction(’approve’/’reject’/’rollback’)、created_at,别依赖主表字段拼历史
  • 执行回退时,先查 approval_log 找上一个非驳回的 step,再校验该 step 的 can_rollback 是否为 TRUE,否则报错 'rollback_not_allowed_for_step_x'

查询「我待处理的审批」为什么越来越慢

因为没索引,或者索引没覆盖查询条件。典型场景是查 WHERE status = 0 AND current_step = 2 AND approver_id = 123,但只在 status 上建了单列索引。

  • 必须建联合索引:INDEX idx_pending (status, current_step, approver_id),顺序不能错:等值查询字段放前面,statuscurrent_step 是高频过滤条件
  • 如果还有按时间排序需求(如 ORDER BY created_at DESC),考虑扩展为:INDEX idx_pending_time (status, current_step, approver_id, created_at)
  • 定期用 EXPLAIN select ... 看是否走了索引;注意 status 如果区分度极低(比如 95% 都是 0),MySQL 可能放弃索引走全表,这时得结合分区或冗余字段优化

真正麻烦的不是建表,而是状态变更的边界条件:谁能在什么时机改哪个字段、失败后要不要回滚、日志和主表怎么保持一致。这些没法靠 DDL 解决,得在应用代码里死守几条 if 判断和事务范围。

text=ZqhQzanResources