字节一面:怎么在千万级订单表加字段?

74 阅读3分钟

沉默是金,总会发光

大家好,我是沉默

面试官:最近,线上出了个“看似简单”的需求:在千万级订单表中新增一个字段,用于业务分析。很多人第一反应可能是:

ALTER TABLE orders ADD COLUMN new_field VARCHAR(255);

但是:订单表可是核心表,数据千万级,一旦锁表,线上业务就可能集体“罢工”!

那么,如何在不影响线上业务的前提下,安全地加字段?

今天,我们简单剖析以下几种方案!

**-**01-

主从切换方案

有人建议:

  1. 在从库上执行 ALTER;

  2. 操作完,把从库提升为主库;

  3. 原主库再降级为从库,同步结构;

  4. 恢复主从。

理论上完美,实际操作门槛极高:

  • 切主从要确保无延迟;

  • 数据一致性要保证;

  • 运维流程复杂,小团队玩不了。

这个方案对业务影响小,但对人要求高

**-**02-

在线DDL方案

不少人推荐 pt-online-schema-change、gh-ost 或 MySQL 8 的 INSTANT DDL。

这些工具本质上是:

  • 创建影子表;

  • 利用触发器同步数据;

  • 最后换个表名,热切换。

听起来高大上,实际上:

  • 有学习成本;

  • 存在触发器延迟;

  • 对切换时机要求高。

适合资深 DBA 操作,新手小白慎用。

**-**03-

扩展表走起!

我们可以这么搞:

建一个 order_extend 表,把扩展字段写进去,主表不动。

order_extend (
  order_id BIGINT PRIMARY KEY,
  new_field_1 VARCHAR(255),
  ...
)

优点:

  • 主表结构稳定;

  • 查询时 JOIN 即可;

  • 字段扩展灵活;

缺点:

  • 查询复杂了点;

  • 程序代码要做处理。

但比起线上崩掉,这点麻烦还可以接受?

**-**04-

高级玩法:JSON字段

有同事建议更进一步:

直接加一个 ext JSON 字段,所有扩展数据往里塞。

{
  "utm_source": "wechat",
  "campaign": "promo-202407",
  "referrer": "vip-user"
}

优点:

  • 无需改表结构

  • 新字段按需加;

  • 查询可按键索引(MySQL 支持 JSON 索引);

在大厂,这种“schema-less”设计已是常规操作。

**-**05-

冗余字段,直接复用

最后我们发现订单表有个字段叫 remark_ext,512 长度,没人用。

我灵光一闪:直接复用这个字段

我们定义格式,封装写入,完美上线。甚至进一步测试:

ALTER TABLE orders MODIFY COLUMN remark_ext VARCHAR(2000);

因为:

  • 扩大字段长度,不锁表;

  • 缩短字段长度,会锁表。

又涨姿势了吧!

总结:

最朴素的智慧:先问一句“真的要加吗?”

我们困在技术细节里,后来我去找产品经理聊了一下:

我:加字段风险大,有替代方案吗?
产品:要这个字段只是为了统计分析,其实写日志就够了。

我???

于是我们直接把字段写入业务日志,由对方系统异步拉日志分析,完美解决。

这事让我明白一件事:

解决问题,不一定得写代码。搞懂“目的”,远比“实现”重要。

这次事件最大的收获:

| 方案

|

特点

|

风险

| | --- | --- | --- |

直接 ALTER简单粗暴高锁表风险
主从切换优雅无感运维复杂
在线 DDL 工具自动化黑盒多、易踩坑
日志落地最经济非结构化、不可 JOIN
扩展表最常规查询略繁琐
JSON 字段高灵活查询难优化
回收字段低成本长度有限

最后送你一句话:

技术最重要的能力,是“先别急着写代码”。

**-**06-

粉丝福利

点点关注,送你互联网大厂面试题库,如果你正在找工作,又或者刚准备换工作。可以仔细阅读一下,或许对你有所帮助!