Antithesis 在 2026 年 4 月发表的一篇技术博客里,回顾了公司早期一个很“土办法但真管用”的设计:为了在 Google BigQuery 上做树状历史追溯,团队把跳表(skiplist)推广成了“跳树”(skiptree),并靠 40 次左右的固定 JOIN,把原本难以承受的递归查询压成一次可执行的分析语句。
这件事的价值,不在于“跳树”会不会成为下一代通用数据结构。大概率不会。它真正说明的是:当你把数据放进分析型数据库时,传统上优雅的树结构往往会立刻变笨;而真正救场的,常常不是更先进的理论,而是愿意为具体约束重写一遍数据模型的工程判断。
不是跳表翻红,而是 BigQuery 把树查询逼成了“异形”
Antithesis 做的是反复运行客户软件、注入故障、观察不同执行路径,最后形成一棵“时间线树”。每条从根到叶的路径,代表一轮测试中随机决策和故障注入造成的结果。问题出在查询:团队想回答“某条日志是怎么一步步走到这里的”,本质上就是沿着 parent pointer 一路向上追祖先。
如果数据放在面向事务的 OLTP 数据库,这不算难题。但 Antithesis 当时把海量测试数据放在 BigQuery,后者擅长全表扫描和聚合,不擅长按 ID 一层层回溯。博客里给出的背景很关键:BigQuery 当时的计费更偏向扫描数据量,而不是计算次数。这意味着,递归式点查会把简单问题变成 O(depth) 次全表扫描,成本和延迟都很难看。Antithesis 没有把树结构拆出去单独存进另一套数据库,因为那会引入双写、一致性乃至 2PC 问题。这个取舍很成熟:很多系统不是死于“算不过来”,而是死于“同步不过来”。
“跳树”真正解决的,是分析型数据库和层级结构的错配
跳树的思路并不复杂:既然一条根到叶的路径像一条链,那就把跳表的“快速跨层跳跃”扩展到整棵树。Antithesis 为每一层建一张 SQL 表,比如 tree0、tree1、tree2,每层大约保留下一层 50% 的节点。每个节点不只记录父节点,而是记录“上一层最近祖先”以及中间被跳过的祖先列表。
这样一来,查询某个节点的完整祖先链时,不再需要递归一层层读,而是顺着更高层的表不断 JOIN,上升时顺手把中间祖先拼回来。博客提到,深树查询大约要写 40 个 JOIN;听起来夸张,但在当时 BigQuery 的计费逻辑下,这类几何分布的多层表,总扫描量大约只相当于两次普通全表扫描。这个工程结果比“SQL 写得难看”重要得多,因为它把一个原本几乎不可在线分析的问题,变成了可运营、可计费、可交付的系统。
这里有个原文没展开、但很重要的现实约束:这种设计之所以成立,前提是树深可预估、查询模式相对固定、而且你愿意用写时复杂度换读时成本。换句话说,它不是通用银弹,更像是为 Antithesis 的工作负载量身定制的索引结构。
和行业常见路线相比,Antithesis 选的是“少动基础设施,多改模型”
很多团队遇到类似问题,通常会在三条路里选一条:换库、加缓存、改模型。Antithesis 选了第三条,而且一用就是公司前六年,直到 2025 年他们开始公开谈自研分析数据库 Pangolin,才逐步摆脱这套 SQL 编译器生成的跳树查询。
| 路线 | 优点 | 代价 | 适用场景 |
|---|---|---|---|
| OLTP/图数据库单独存树 | 点查快,递归自然 | 双写、一致性复杂 | 树结构是核心资产 |
| BigQuery 原生硬查 | 实现简单 | 深度查询成本高、慢 | 偶发分析、低频查询 |
| Antithesis 跳树 | 保持单库分析,成本可控 | 数据建模复杂,SQL 很长 | 查询模式稳定、数据量极大 |
| 自研数据库(如 Pangolin) | 能按工作负载优化 | 成本最高,维护重 | 规模足够大、需求独特 |
这也是这篇文章最有参考价值的地方。它不是在教开发者“都去学跳表”,而是在提醒企业技术负责人:当底层数据库不适合你的查询模式时,最贵的方案往往不是性能最差的那个,而是看似“架构最正统”的双系统拆分。现实里,采购不会立刻批准一套新数据库,数据平台团队也不愿接一个额外的一致性炸弹,最后真能落地的,往往是这种有点别扭、但能跑六年的中间解。
如果你是这几类人,最现实的影响很不一样:
- 数据工程师会重新审视表结构,而不是只盯 SQL 优化。
- 测试平台团队会更在意“查询形状”和存储引擎是否匹配。
- 技术管理者会更谨慎地评估双写和 2PC 的组织成本。
- 普通开发者则会得到一个反常识结论.冷门数据结构有时比流行框架更救命。
这套方法不该被神化,它更像一张特定年代的工程账单
原文最后提到,作者后来发现“跳树”和学术界已有的 skip graph 很接近。这恰好说明一件事:很多工程创新,本质上是把旧理论重新压进新约束里。它未必新,但足够合适。Antithesis 还顺带认同数据库学者 Andy Pavlo 的一个判断:写得好的树结构通常还是比跳表强。这个判断我基本同意。
所以,这篇文章不重要的地方也很明确:它不是一个通用产品发布,不是数据库行业马上要跟进的新标准,也不是你该立刻复制到业务系统里的最佳实践。它的重要之处,在于它留下了一份罕见的工程决策样本:为什么一家公司宁可写出以 KB 计的 SQL、再用 JavaScript 编译器生成查询,也不愿意轻易拆成两套数据库。很多技术文章只展示成功方案,不展示当时被放弃的方案;Antithesis 这次把那些脏活和妥协也讲出来了,这比“算法多优雅”更有参考价值。
