先判断缺的是“存储位置”还是“业务含义”。如果新需求只是给已有内容补一个可空属性,保留原表加字段通常最省;如果新需求会改变同一类记录的归属、状态流转或统计口径,继续在旧表上叠字段往往会把问题推迟到下一次改版。扩展前先冻结一周内的写入,导出一份真实数据做映射演练,再决定保留、改写还是让旧结构退出。
适用前提是:旧字段仍被至少一个在用页面读取,新需求与旧字段属于同一业务对象,且新增值允许为空。此时可以走“加列—回填—双读”的顺序。
假设某黄石本地企业的产品表原本只有“规格”一个文本字段,后来要拆成“长度、宽度、材质”三项。若前台只展示拼接后的规格,后台录入也只有一个输入框,那么加三列并保留原列是成立的;回填时把旧文本按分隔符拆开,拆不出的记录留在待处理列表,而不是默认填零。这个动作的结果会直接决定下一步:待处理记录多,说明旧数据本身不规范,应先做人工清洗,而不是急着把新列设为必填。
当旧字段的含义已经不够精确,比如“状态”原本只有启用和停用,现在要区分草稿、待审、已发布、已下架,继续复用同一列会让历史数据无法解释。改写的前提是能明确旧值到新值的映射规则,并且能找到所有写入该字段的入口。
实际动作分三步:先在代码里搜索该字段的写入点,列出后台表单、批量导入、接口和定时任务;再建立映射表,把旧值逐一对应到新值,无法对应的单独标记;最后让旧入口停止写入,新入口只写新结构。判断是否完成的关键不是新页面能打开,而是旧入口是否真的不再产生数据。若只改了读取端,旧任务仍会写入旧值,几天后统计口径就会再次混乱。
退出不是删除,而是把旧表或旧字段移出主流程。适用前提是:读取端已全部切换,写入端已停止,且保留一份可查询的历史快照。常见隐性依赖包括报表脚本、导出模板、第三方对接和缓存中的旧结构。
可以按下面顺序验证:
如果关闭后请求量或抓取量出现下降,不能直接认定是字段退出造成的。缓存过期、入口调整、外部链接变化都可能产生同样现象,需要结合服务端日志和访问来源一起看,再决定回滚还是继续。
把最近一个月的真实数据导出,按新结构写一份映射脚本,统计三类结果:能直接映射、需要人工判断、无法映射。能直接映射占比高,优先保留加列;需要人工判断集中在一两个旧值,优先改写语义;无法映射的比例高且旧字段已无页面读取,才考虑让旧结构退出。
这个演练的价值在于把“字段不够用”拆成可比较的证据,而不是凭感觉一次改完。演练中发现的新问题,比如某接口仍在写旧值,应作为下一步的修复项,而不是继续加字段掩盖。
无论选哪种方式,都应保留旧数据的只读副本和一份字段对照说明。回退路径不需要复杂,但必须能在新结构出现异常时,让旧页面继续读到可用值。扩展完成后的检查重点不是字段数量,而是同一业务对象在不同页面、导出和统计中是否得到一致结果。若不一致,说明还有写入路径没有收口,应先处理它,再继续增加新字段。