能扩,但前提是先分清“加字段”和“改结构”是两件事。如果原表只是缺几个可空字段,通常可以增量迁移;如果缺的是新的实体关系,比如一个客户对应多个联系人、一个订单对应多次付款,那么继续在原表上堆列,往往会在下一次需求到来时再次卡住。判断依据不是字段数量,而是新数据与旧数据是“一对一”还是“一对多”。
把待补的数据写出来,逐条问一句:这条数据跟现有记录是几条对几条。若是每条现有记录最多配一条新数据,例如给文章加“最后校对时间”,加列即可;若是可能配多条,例如给产品加“多张规格图”“多个供应商报价”,就应该新建关联表,用外键指回原记录。
一个可执行的判断动作:在纸上列出旧表主键,再写三条样例数据。如果三条样例里出现同一个主键重复,说明是“一对多”,加列会失败。这个动作的结果直接决定下一步是写 ALTER TABLE 还是建新表,避免先加列、再拆列的二次返工。
第一,你要能拿到数据库的写权限或迁移权限。很多上线后的站点,开发账号只有读写业务表的权限,没有改结构的权限。这种情况下,先申请一次性迁移窗口,而不是在业务高峰期直接改。
第二,旧数据要允许为空。新增字段若设成非空且无默认值,已有记录会直接写入失败。因此扩展字段时,先允许 NULL,回填完成后再按需要收紧约束。若旧数据无法回填,就不要急着加非空约束。
缺少完整数据或权限时,仍可执行的最小动作是:先在本地或测试库跑一遍迁移脚本,记录每条语句影响的行数,再决定是否上生产。这个动作只能说明脚本在测试库可执行,不能推出生产环境一定无锁表风险,也不能说明业务字段设计已经合理。
假设一个遵义本地的服务类站点,最初只存“客户姓名、电话、留言”。上线后运营想记录“每次跟进的时间、跟进人、结果”。看起来是给客户加几个字段,但同一客户会被不同人跟进多次,这是典型的一对多。
如果硬加“跟进1时间、跟进1人、跟进2时间”这样的列,第三次跟进时又要改表。正确做法是新建跟进记录表,字段为:客户ID、跟进时间、跟进人、结果。原客户表不动,只加一个可空的“最近跟进时间”作为查询冗余。这个反例说明:判断依据是数据重复出现的可能性,而不是当前需要几条。
按以下顺序执行,可以把风险控制在可回退范围内:
每一步的结果决定下一步是否继续:若回填后新字段仍有大量空值,先查清是历史数据本身缺失,还是回填条件写错,不要直接进入收紧约束阶段。
权限不足时,可以先产出字段清单和迁移脚本草稿,交给有权限的人评审,而不是等着权限到位再动手。数据不完整时,先区分两类缺失:一类是旧记录本来就没有这项信息,只能留空;另一类是采集环节漏了,需要在表单或接口层补上。前者靠加可空字段解决,后者要先改采集逻辑,否则新字段会继续产生空值。
需要提醒的是,字段扩展后请求量、写入量或某项统计暂时归零,不能单独证明迁移成功或失败,也可能是缓存未刷新、定时任务未跑或查询条件写错。下一步动作应是抽查若干条新旧记录做对照,而不是只看总量指标。
扩展数据模型的核心不是一次加多少字段,而是让新数据有地方放、旧数据不被破坏、回滚有依据。先把一对多关系识别出来,再决定加列还是建表,后续需求到来时就不必反复改动同一张表。