先判断一件事:新字段是让现有业务继续跑下去的必要条件,还是只是让页面看起来更丰富。如果是前者,优先在现有结构上扩展;如果旧结构已经无法表达业务规则,再考虑改写或退出。判断依据不是字段数量,而是这个字段是否参与筛选、统计、权限或对外接口。
扩展数据字段的代价通常来自三处:数据库结构、业务代码、历史数据。三者中只要有两处需要同步改动,就应该把它当成一次小迁移来处理,而不是随手加一列。
可以先做一个动作:把新需求写成三句话——谁写入、谁读取、为空时业务是否还能继续。如果第三句的答案是“不能继续”,说明这个字段属于关键路径,必须先设计默认值和回填规则,再动代码。
旧结构仍值得保留,通常满足这几个前提:旧字段没有被误用、表的数据量还没有大到改结构会明显影响写入、业务规则没有发生方向性变化。此时扩展是合理的,但要遵守两条约束。
第一,新字段尽量可空,并给业务代码一个明确的空值行为,例如列表页显示占位、导出时留空、统计时排除。第二,如果新字段要参与筛选,先确认现有查询是否已经依赖旧字段的组合条件;一旦混用,后续排查问题会变困难。
假设一个场景:某业务原有“客户等级”字段,现在要增加“来源渠道”。如果渠道只用于后台备注,加一个可空字段即可;如果渠道要进入报表分组,就需要同时确认历史订单的渠道如何回填。回填规则没定之前,报表数字会先出现异常,这时应暂停上线报表,而不是先改页面。
出现下面任一情况,保留旧结构会越拖越贵:同一字段在不同页面被赋予不同含义;需要按新维度做权限隔离;旧字段的取值已经无法覆盖新业务;或者多个新需求都指向同一张表的重构。此时应把扩展升级为一次有计划的改写。
改写的实际动作不是直接改线上表,而是先建立新旧字段的映射关系,再决定历史数据是回填、保留双写,还是只对新数据生效。选择哪一种,取决于旧数据是否还要被查询。如果旧数据只用于存档,可以只对新数据启用新结构;如果旧数据仍参与统计,就必须回填,并在回填完成前避免用新字段出报表。
退出不等于放弃网站,而是放弃在当前结构上继续叠加。判断信号是:每次新增字段都要改动多处互不相关的代码;字段之间的依赖关系已经无法用文档说清;或者业务方开始绕过系统,用表格单独维护数据。出现这些信号时,继续加字段只会让问题更隐蔽。
退出的前提是明确迁移边界:哪些数据必须带走,哪些可以留在旧系统只读,切换期间两边如何避免同时写入。边界没定清楚之前,不建议开始迁移,否则新旧数据会互相覆盖。
这套顺序的作用是让每一步的结论决定下一步:如果第一步发现字段属于关键路径,第二步就不应该跳过索引和查询条件的评估;如果第三步确认无法回填,第四步的验证重点就应放在新旧数据的分界上。扩展数据字段本身不是难题,难的是在动手之前承认旧结构已经承担了什么,以及新需求是否真的属于同一层业务。