能扩展,但先别急着在旧表上加字段。真正要先判断的是:缺的是“存不下的信息”,还是“同一信息被塞进了错误的位置”。前者通常可以通过新增从表或键值扩展表解决;后者如果继续加字段,往往只会让查询和录入越来越乱。下面给出区分两种情况的证据,以及在南昌网站开发项目里可执行的迁移顺序。
上线后最常见的矛盾是:业务人员说“这个表单还要加三个选项”,而技术人员看到的是同一张主表已经被加了十几个可空字段,查询时不得不写一长串 CASE WHEN。表面看是字段不够,实际可能是三类信息混在了一起:
如果多值属性被硬塞进主表的多个列,例如 contact1、contact2、contact3,那么第四次扩展时就不只是加字段,而是要改代码、改导入模板、改历史数据。字段不够用只是表象,结构错位才是根因。
解释一:结构错位。 原有字段本来就不该是“一列一个值”。例如订单备注、客户标签、产品规格,天然是一对多关系。此时正确动作是拆出从表,而不是继续加列。
解释二:业务新增了真实维度。 例如原来只记录“是否开票”,现在要记录“开票类型、税率、开票主体、备注”。这些是同一业务对象上的新属性,且每条记录最多一个值,适合在主表或独立的业务扩展表中新增字段。
两种解释对应的迁移成本完全不同。结构错位越晚处理,历史数据清洗越贵;真实新增维度如果被过度拆表,又会让简单查询变复杂。关键不是选“加字段”还是“拆表”,而是先确认信息本身的基数。
可以用下面三组证据判断属于哪一种:
OR 连接同类字段,例如 contact1 IS NOT NULL OR contact2 IS NOT NULL。这类写法越多,越说明字段被当成了数组。假设一个南昌本地服务类网站,上线时客户表只有 name、phone、remark。三个月后需要记录每个客户的多次回访。若直接把回访内容追加到 remark 里,查询“上周谁被回访过”就只能靠文本匹配;若新建 follow_up 从表,记录客户 ID、回访时间、回访人、内容,则同一问题变成一次带时间范围的关联查询。这个例子是假设,用于说明判断方法,不代表任何具体项目结果。
确认属于多值属性后,建议按以下顺序动作,而不是先改表结构:
这个顺序的结果是:旧页面在迁移期间仍可访问,新数据不再产生新的结构债。如果跳过冻结直接双写,后续很难判断某条记录到底以哪边为准。若确认只是真实新增维度,且每条记录只有一个值,则在主表加字段并补默认值即可,但要同步更新导出模板和接口文档,否则下游报表会出现空列。
扩展完成后,至少验证三件事:新增记录能否正确关联到原记录;按时间或状态筛选时,从表数据是否会被重复计算;导出和接口返回的字段名是否与旧版兼容。页面能打开不代表数据关系正确。如果发现同一客户在列表中重复出现,通常是关联查询缺少去重或聚合,而不是字段本身有问题。
另外,请求量或抓取量在迁移后短暂波动,不能单独证明扩展动作正确或错误。缓存、重定向、日志采样、爬虫调度变化都可能造成类似现象。要判断扩展是否生效,应直接核对数据库中的关联记录数量和业务侧可读性,而不是依赖单一外部指标。
最后,如果业务方仍在不断提出“再加一个字段”,先回到基数判断。能拆成从表的,不要继续加列;确实属于单值新属性的,再加字段并同步更新所有出口。这样下一次扩展时,你面对的是新增一张关联表,而不是重写整张主表。