开发文档

鲜花交易系统与鲜花交易平台(PHP / ThinkPHP 版)的研发记录:功能上线、架构演进与实施经验,按发布日期持续更新。

删掉空壳表:为什么"先留着以后可能用"是最贵的决定

这次清理了什么

两处最早期的"预留":

  1. 一张空壳表:早期规划文件配置时建的表,后来文件配置统一收口到「网站配置」,这张表既没有数据,也没有任何代码引用;
  2. 一列悬空列:附件表上的配置业务号,用来关联上面那张表。表不用了,这一列就变成了永远为空的字符串。

它们不影响功能,但会持续制造误解:新人读表结构时会问"这张表干嘛的",写文档时要在"已废弃"上做标注,做数据备份时它还占着空间。

判定标准:三个"零"才动手

删表最怕删错。我们确立了三条判定,全部满足才允许删:

判定检查方式说明
零代码引用全仓库搜索表名与列名(含注释、文档、脚本)排除"代码里还读它"的情况
零数据SELECT COUNT(*) 为 0有数据先迁移或导出,不允许"删表即丢数据"
零外键引用检查其它表是否有列以此表业务号为关联关联关系不写外键,必须人工核对

三条里最容易被忽略的是第三条:这张空壳表没有被任何表引用,但删列前必须确认没有其它表上的同名列依赖它(例如附件表的配置业务号是否被别的查询用到)。

执行顺序:先删代码,再删列,最后删表

顺序反了会有一段"代码引用不存在的列"的窗口期。正确顺序是:

  1. 删除/改写所有引用该表该列的服务端代码、接口文档、前端类型定义;
  2. 生成一次迁移:先删列,再删表(一条迁移里两步,配回滚脚本);
  3. 执行迁移,跑冒烟;
  4. 同步权威文档(表数、表清单、字段说明)与建库脚本;
  5. 全库再扫一次,确认没有残留引用。

第 4 步是纪律问题:表结构有两份真源(数据库和设计说明书)时,只改一份就等于埋下第二笔技术债。这也是我们后来引入迁移台账的原因——让"哪次改动、改了什么"本身可查。

为什么"留着以后可能用"是坏习惯

预留看起来零成本,实际成本在三处:

  • 认知成本:每张表都要在文档里解释,读者要判断哪些是活的;
  • 维护成本:备份、权限、数据体检、迁移脚本都要覆盖它;
  • 决策成本:下次真要做这个功能时,会纠结"用旧表还是新建",而旧表的结构往往已经不符合当前设计。

真正需要预留的是能力(比如租户两列、软删除标记),而不是不存在功能的空表。前者改动成本高,后者重建成本几乎为零。

一个可以复用的判断

如果一张表满足"没有数据、没有代码、没有人能说清它的用途",它就应该被删掉,而不是被保留。

我们从建库到这次清理大约三周,删掉了两处早期预留,同步改了文档与建库脚本。这类小清理做得越早越便宜——等到表里有了几百行来路不明的数据,就只能永远留着它了。

本文属于「开发文档」系列,记录鲜花交易系统(PHP + ThinkPHP 8 + MySQL 8)的实际研发进展。想了解功能清单与报价,可前往系统报价或联系我们。