先给结论:上线后发现字段不够用,通常不必推翻现有数据结构,而是先判断这个字段是“展示补充”还是“关系变化”。如果只是给已有对象增加一个可空属性,优先做增量迁移;如果新需求要把一条记录拆成多条、或让多个角色对同一事实各自维护版本,就要先补一层中间结构,再改读写路径。下面用一个假设情境把决策过程走一遍。
假设一个内容型网站上线三个月,最初的表单只收了姓名、电话、留言。运营想按“来源渠道”分组回访,销售想记录“每次沟通结果”,客服想标记“是否已解决”。三个人都说“加个字段就行”,但他们对“客户”这个对象的理解并不相同:运营眼里一个电话是一条线索,销售眼里一次沟通是一条记录,客服眼里一个问题是工单。
如果直接在主表上连续加列,很快会出现一行里塞进多次沟通结果、多个解决状态的情况,后续查询和统计都会变得难以解释。所以第一步不是写迁移脚本,而是把分歧转成可以核对的项目:列出每个角色要回答的问题、每个问题需要的最小字段、以及这些字段属于哪个对象。
把新需求归类,能避免用同一种方案处理所有情况:
判断依据可以很具体:如果新字段的取值会随每次操作不断追加,它大概率属于第二类;如果不同角色会对同一行给出不同结论,它属于第三类。只有第一类适合直接在主表上加列。
假设归类后发现“沟通记录”属于一对多、“解决状态”属于多角色状态。可以按下面的顺序推进,每一步的产出都会决定下一步是否继续:
这个顺序的关键在于:每次只改一层,并且用可核对的对比结果决定是否进入下一步。请求量或抓取量在迁移期间出现波动,可能来自缓存、部署或爬虫重试,不能单独作为“迁移成功”或“迁移失败”的证据。
出现下面任一情况,继续增量扩展的维护成本会超过重构成本:
反之,如果新需求仍能用可空字段表达、旧数据不需要回填、读写路径只有一处,那么增量扩展更稳妥。重构不是更“正确”,只是在对象边界已经变化时才更划算。
回到开头的假设情境,真正让扩展顺利的不是某个工具,而是两个动作:一是让每个角色用一句话写出“我要回答的问题”,二是把这些问题映射到对象和字段上,形成一份可以逐条打勾的清单。清单完成后,任何新增需求都先问一句:它属于补充属性、一对多关系,还是多角色状态?答案不同,改动范围就不同。
这样做的结果是,扩展不再依赖某个人对“客户”的默认理解,而是依赖一份大家都能核对的字段归属。下一步无论是加列、建关联表还是调整状态字段,都能说清改动影响哪些页面、哪些历史数据需要处理,以及验证时该看哪一组对比结果。