字段不够用,通常不是加一列就能收场。先判断现有字段是否已被程序、模板或接口硬编码引用:如果只是展示层缺字段,可以增量添加;如果字段语义已被写入业务逻辑,直接加列会让旧数据和新数据含义混在一起,需要先做一次字段拆分或归档,再扩展。
第一类是容量型不够:字段存在,但长度、精度或枚举范围不够。比如一个 status 字段原本只允许“待处理/已完成”,现在要加“部分退款”,这属于枚举扩展,改动小,风险集中在旧代码对未知值的处理。第二类是维度型不够:原本一条记录只对应一个值,现在需要一对多。例如商品表只有一个 supplier_name,业务却要记录多个供货批次和对应价格。这类问题加列解决不了,必须新建关联表。
判断依据可以看一个信号:新需求是否要求同一主体同时保存多个不同值。如果是,加列只会导致 field_1、field_2 无限膨胀,最终查询和统计都变得不可靠。
如果确认字段只出现在模板输出和后台列表里,没有参与计算、筛选或对外接口契约,可以按增量方式处理。实际动作是:先加可空新字段,再回填历史数据,最后改展示层读取新字段。回填时保留旧字段一段时间,等确认没有页面或导出还在读旧值,再决定是否删除。
这个动作的结果会直接影响下一步:如果回填后旧字段仍有非空写入,说明还有未发现的写入路径,此时不能删旧字段,应该先定位写入来源。反过来,如果旧字段停止写入且读取为零,才进入清理阶段。注意,读取量归零也可能只是缓存或定时任务尚未触发,不能单独作为删除依据,需要结合写入日志和任务调度记录一起看。
当字段参与金额计算、权限判断或对外接口返回时,加列等于同时改变数据契约。此时更稳妥的做法是先拆语义:把“状态”拆成“支付状态”和“履约状态”,把“地址”拆成“省市区”和“详细地址”。拆分后新旧字段并行,接口按版本切换,而不是在原字段上追加含义。
假设一个订单表原本用 order_status 同时表达付款和发货,现在要支持部分发货。直接加一个 ship_status 会让两个字段出现组合爆炸,旧代码读到 order_status=已发货 却不知道是否全部发出。更清晰的做法是保留 order_status 表示订单整体状态,新增 shipment 关联表记录每次发货,页面和接口改为读关联表。这个假设说明的是比较方法:先看一个字段是否承担了多个独立语义,再决定加列还是建表。
例外情况是数据量很小且没有对外接口,可以跳过双写,直接停机迁移。但只要存在外部调用方,就不能假设对方会同步升级,接口字段的删除应晚于新字段上线,并给出过渡期。
字段扩展的真正难点不在加列,而在判断旧字段是否还承担着未被记录的语义。先做引用清单,再决定增量添加还是拆表重建,才能让后续的清理和接口切换有明确依据。