如何设计数据库分类、标签与预算科目
分类不是下拉框文案,而是历史账目的解释口径。
这页只讲一件事:“餐饮”改名、隐藏、合并之后,历史月报为什么不能乱。
| 事故 | 根因 | 设计动作 |
| “餐饮”改成“业务招待”,过去月报全变。 | 账目只看当前分类名。 | 账目引用稳定 category_id,必要时保存名称快照。 |
| 删除旧分类后,历史账目无分类。 | 把停用当成物理删除。 | 分类只隐藏或归档,不断历史引用。 |
| 移动分类树后,去年汇总变了。 | 历史报表跟着当前树跑。 | 明确只影响未来,或生成历史重算批次。 |
| 标签被拿去扣预算,一笔账扣多个预算。 | 标签、分类、预算科目混用。 | 分类是主统计口径,标签是弱描述,预算科目是控制口径。 |
| 导入规则把 Apple 都归成水果。 | 自动分类没有规则版本和确认。 | 保存规则版本、候选分类和置信度。 |
判断:只要分类进入报表、预算或导入规则,改分类就是一次数据变更,不是改文案。
| 问题 | 最低设计 |
| 这是分类、标签、字典,还是预算科目? | 先分层,避免弱描述承担强控制。 |
| 它属于哪个账本或租户? | 带 ledger_id 或 tenant_id。 |
| 历史账目看当前名称还是当时名称? | 保存稳定 ID,必要时保存名称 / 路径快照。 |
| 不再使用怎么处理? | 隐藏、归档、合并映射,不直接删除。 |
| 分类变化是否影响预算和报表? | 预算映射、报表口径要有版本或生效期。 |
categories:
category_id, ledger_id, parent_category_id
display_name, category_type, status
effective_from, effective_to, merged_to_category_id, version
ledger_entries:
entry_id, category_id
category_name_snapshot, category_path_snapshot, category_version
budget_mappings:
category_id, budget_item_id
effective_from, effective_to, version
| 样本 | 通过标准 |
| 改分类名称。 | 历史账目仍能解释当时名称和当前名称。 |
| 隐藏分类。 | 不能新建该分类账目,但旧账不断链。 |
| 合并分类。 | 先 dry-run 展示影响范围,再确认重算派生结果。 |
| 预算映射改版。 | 旧月份报表不被静默重写。 |
| 导入规则误命中。 | 能按规则版本圈定候选并批量修复。 |
记住:分类要稳定,标签要轻,预算科目要有版本。不要让一个下拉框同时承担三种职责。