先判断一件事:新字段是“补充描述”还是“参与筛选和计算”。只补充描述,走增量扩展即可;一旦要参与筛选、排序、统计或对外接口,就必须先做数据迁移和回填,再改代码。判断错方向,后面返工的成本远高于多花几天做迁移。
这类需求最常见,比如内容页要加一个“适用人群”说明,或产品页要加一段“包装规格”。它的特征是:旧记录没有这个值也不影响原有功能,前端只负责有值就显示、无值就不显示。
实施动作可以按这个顺序走:先在策划方案里补上字段定义,包括字段名、类型、是否必填、默认值;再在数据库加列或加一张扩展表;然后在后台表单和前台模板里接入;最后只对新增和编辑的内容生效,旧内容保持空值。
这个动作的结果会直接影响下一步:如果旧数据留空不影响用户判断,就不需要回填,可以立即上线;如果留空会让页面出现明显断裂(比如列表里一半有、一半没有),那就要先决定是统一隐藏该模块,还是安排一次性补录。补录属于内容工作,不属于技术工作,排期时要单独留人力。
这时字段不再是“附加说明”,而是数据模型的一部分。典型信号是:运营要用它做筛选条件、报表要按它分组、接口要把它返回给第三方。旧数据留空会导致筛选结果缺失、统计口径不完整。
必要适用条件:只有当你能明确这个字段的取值范围和空值含义时,才适合直接加约束。取值边界不清,就先按可空字段上线,观察一段时间再收紧。
实施动作分三步:
回填完成后的结果决定了能否进入下一步:如果仍有大量记录无法确定取值,就保留可空状态,并在筛选逻辑里显式处理“未知”这一类,而不是强行填一个默认值。强行填默认值会让后续统计失真,而且很难再区分哪些是真实值、哪些是补的。
三种方式对应不同的增长预期,选择依据是“这个字段以后会不会变成一组”。
假设一个场景:某内容站原本只有“作者”一个字段,后来要支持“作者+译者+审校”三个角色。如果继续加列,每加一个角色就改一次表;如果改成关联表,角色数量变化时只增加数据行。这个例子只用于说明判断方法,不代表任何具体系统的实现。
扩展往往伴随清理。旧字段、旧接口、旧合作方提供的数据源,不要一次性删除,先区分三类:仍被引用的、仅历史留档的、确认无用的。
仍被引用的字段先保留并标记为废弃,等调用方全部切换后再移除;仅历史留档的可以迁到归档表或导出文件,主表不再保留;确认无用的才删除。这个顺序的意义在于:删除是不可逆动作,而标记废弃是可逆的,先做可逆的那一步,出问题还有退路。
与旧合作关系相关的数据源同理:如果对方仍在提供字段,但你的新模型不再使用,先停止写入、保留历史数据,而不是立刻清空。清空之后如果发现还有报表依赖它,恢复成本会很高。
出现下面任一情况,说明增量扩展已经不够,应该回到策划方案层面重新设计数据结构:同一张表在短时间内反复加列;新字段需要跨多张表拼接才能得到完整含义;筛选条件开始依赖字段之间的组合规则,而不是单字段取值。
重新设计不等于推倒重来。可以保留现有表作为读写层,新建一张结构更清晰的主表,通过同步或视图过渡,等新表稳定后再切换。这样旧系统可以继续服务,新需求也不必继续挤在旧结构里。