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

来源:这里教程网 时间:2026-02-28 20:49:49 作者:

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

直接用

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

状态值必须有明确业务含义,写进注释里,比如:
COMMENT '0:pending,1:approved,2:rejected,3:withdrawn'
避免用负数或超大整数当状态码,MySQL 的
TINYINT
范围是 -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_id
operator_id
action
('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)
,顺序不能错:等值查询字段放前面,
status
current_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 判断和事务范围。

相关推荐