字段不够用通常不是数据库存不下,而是早期建模把“展示需要什么”当成了“业务会记录什么”。扩展前先判断一件事:新信息是已有记录的补充属性,还是会产生多条记录的新实体。前者适合加字段,后者适合加表;判断错方向,后面每加一次都要回头改代码。
如果新需求是给每条已有记录多存一个值,比如给每个产品补一个“适用季节”,那属于缺属性,加字段即可。如果新需求是“一个产品对应多个供应商报价”,每条产品要挂多条数据,这就不是加字段能解决的,硬塞进一个字段里会变成逗号拼接的字符串,之后无法按供应商筛选、排序或统计。
区分方法很直接:问这个新信息对同一条主记录会不会出现两个以上不同的值。会,就是缺实体,要新建关联表;不会,才是缺属性。假设一个订单表,上线后业务想记录“每次修改订单状态的人和时间”。一条订单会被改多次,这是缺实体,应该建一张订单变更记录表,而不是在订单表上加“修改人1、修改人2”这样的字段。这个假设例子说明的是判断方法,不是某个项目的实际结果。
加字段成立的条件是:新值对每条记录最多一个,且查询时总是跟着主记录一起取出,不单独统计。实施动作通常是三步:先在数据库加可空字段,再在写入和读取逻辑里补上这个字段,最后才在页面展示。顺序很重要,先改页面会导致读取空值报错。
可空字段加完,要确认旧数据怎么处理。如果旧记录允许为空,前端要能显示“未填写”而不是空白或报错;如果业务要求必填,就得先给旧记录补默认值,再把字段设为非空。这个动作的结果会决定下一步:如果旧数据无法合理补默认值,说明这个字段其实不是每条记录都适用,应该考虑拆到单独的表里,只给需要它的记录建行。
加表成立的条件是:新信息会一对多,或者需要独立查询和统计。实施动作是建一张带主记录标识的新表,把多条明细写进去,读取时按主记录标识关联查询。代价是查询变复杂,列表页如果要显示明细数量或最新一条明细,需要额外处理,不能像加字段那样直接读一列。
这里有个容易被忽略的取舍:加表之后,删除主记录时明细怎么办。要么级联删除,要么保留孤儿数据但明确标注。选哪个取决于明细是否有独立价值。如果明细只是主记录的附属说明,级联删除更干净;如果明细本身有审计意义,就不能随主记录一起消失。这个决定要在建表时就定下来,事后改会牵动已有数据。
不要凭感觉选。可以查三类证据:一是看现有数据里同一个主记录是否已经出现重复值迹象,比如某字段里出现分隔符;二是看业务方描述需求时说的是“每条”还是“每次”;三是看未来查询会不会按新信息筛选。如果会按新信息筛选,加字段后仍要全表扫描字符串,加表才能建索引。
有一个反常现象值得注意:有时加完字段后页面正常,但搜索或筛选功能对新字段无效。这不一定说明字段加错了,也可能是查询逻辑没有把新字段纳入条件。请求量或抓取量没有变化,同样不能证明字段设计正确,它只说明这次改动没有影响外部访问,内部数据是否可用还得单独验证。
例外情况是:如果系统还在频繁调整阶段,业务自己也说不清新信息会不会变成一对多,可以先用一个过渡字段承载,但要在字段命名或备注里标明它是临时的,并约定一个复核时点。过渡字段长期留存会变成技术债,所以复核时要重新走一遍前面的判断。
收尾动作建议固定为:改完数据结构后,用一条旧记录和一条新记录分别走一遍写入、读取、筛选,确认旧数据不报错、新数据能查到。这个动作的结果决定是否可以继续在页面上暴露新字段;如果旧记录读取异常,先回退展示层,不要继续加更多字段。