这次清理了什么
两处最早期的"预留":
- 一张空壳表:早期规划文件配置时建的表,后来文件配置统一收口到「网站配置」,这张表既没有数据,也没有任何代码引用;
- 一列悬空列:附件表上的配置业务号,用来关联上面那张表。表不用了,这一列就变成了永远为空的字符串。
它们不影响功能,但会持续制造误解:新人读表结构时会问"这张表干嘛的",写文档时要在"已废弃"上做标注,做数据备份时它还占着空间。
判定标准:三个"零"才动手
删表最怕删错。我们确立了三条判定,全部满足才允许删:
| 判定 | 检查方式 | 说明 |
|---|---|---|
| 零代码引用 | 全仓库搜索表名与列名(含注释、文档、脚本) | 排除"代码里还读它"的情况 |
| 零数据 | SELECT COUNT(*) 为 0 | 有数据先迁移或导出,不允许"删表即丢数据" |
| 零外键引用 | 检查其它表是否有列以此表业务号为关联 | 关联关系不写外键,必须人工核对 |
三条里最容易被忽略的是第三条:这张空壳表没有被任何表引用,但删列前必须确认没有其它表上的同名列依赖它(例如附件表的配置业务号是否被别的查询用到)。
执行顺序:先删代码,再删列,最后删表
顺序反了会有一段"代码引用不存在的列"的窗口期。正确顺序是:
- 删除/改写所有引用该表该列的服务端代码、接口文档、前端类型定义;
- 生成一次迁移:先删列,再删表(一条迁移里两步,配回滚脚本);
- 执行迁移,跑冒烟;
- 同步权威文档(表数、表清单、字段说明)与建库脚本;
- 全库再扫一次,确认没有残留引用。
第 4 步是纪律问题:表结构有两份真源(数据库和设计说明书)时,只改一份就等于埋下第二笔技术债。这也是我们后来引入迁移台账的原因——让"哪次改动、改了什么"本身可查。
为什么"留着以后可能用"是坏习惯
预留看起来零成本,实际成本在三处:
- 认知成本:每张表都要在文档里解释,读者要判断哪些是活的;
- 维护成本:备份、权限、数据体检、迁移脚本都要覆盖它;
- 决策成本:下次真要做这个功能时,会纠结"用旧表还是新建",而旧表的结构往往已经不符合当前设计。
真正需要预留的是能力(比如租户两列、软删除标记),而不是不存在功能的空表。前者改动成本高,后者重建成本几乎为零。
一个可以复用的判断
如果一张表满足"没有数据、没有代码、没有人能说清它的用途",它就应该被删掉,而不是被保留。
我们从建库到这次清理大约三周,删掉了两处早期预留,同步改了文档与建库脚本。这类小清理做得越早越便宜——等到表里有了几百行来路不明的数据,就只能永远留着它了。