题干与适用场景
关系型数据里有客户、账户和转账关系。面试官要求你回答:什么时候应使用 BigQuery Graph,什么时候保留递归 SQL,并设计一套可验证的迁移与回退方案。
题目针对数据工程、分析工程和数据平台岗位。假设数据已经位于 BigQuery,图能力仍处于 Preview;不能把 Preview 当作无条件的生产承诺。目标是比较多跳关系表达、治理、成本和兼容性,而不是证明某一种查询语言永远更快。
面试官考察点
面试官会关注你能否先识别关系查询的形状,再选择图模式或关系模式;能否区分业务语义、执行计划和平台生命周期。强回答会说明图模式如何与现有表共存、何时递归 SQL 更简单,以及如何用同一组基准结果验证迁移。
回答前需要澄清的问题
- 查询是固定深度的层级展开,还是深度和路径条件经常变化?
- 需要返回节点、边和路径,还是只需要聚合后的指标?
- 图数据是批量分析,还是要求低延迟在线遍历?
- 结果是否必须与现有 SQL 报表逐行一致,允许多长的 Preview 兼容窗口?
- 预算、扫描量、并发、数据新鲜度和下游客户端版本约束是什么?
30 秒回答框架
“我先按查询形状和交付目标分流:固定一到两层、简单聚合且已有 SQL 资产的场景保留 SQL;多跳模式、路径条件和关系复用频繁时评估 BigQuery Graph。先建立节点、边、标签和主键约束,再用同一批快照对比 GQL 与递归 SQL 的结果、扫描量、延迟和成本。Graph 处于 Preview,所以采用影子执行和可回退的 SQL 主路径,闸门通过后再扩大。”
分步骤深入解答
1. 先把关系问题写成图问题
把 Person、Account 作为节点,把 Owns、Transfers 作为有方向的边;为每条边定义时间、金额和唯一标识。若问题是“找三跳内可达账户并按风险聚合”,图模式能直接表达路径;若问题只是按日期分组统计转账金额,关系表和普通 JOIN 更容易审计。
2. 用查询形状决定技术路线
固定深度、固定表结构且只返回指标时,递归 SQL 的可读性和现有权限模型通常更有价值。深度变化、路径模式复用、节点和边需要同时返回时,GQL 的 GRAPH、MATCH、NEXT 和 RETURN 让意图更接近业务关系。选择依据是变化频率和维护成本,不是把 GQL 当成 SQL 的全面替代。
3. 建模并固定语义边界
先定义标签、方向、可空属性、时间有效期和重复边处理。规定同一业务关系的主键,避免重复加载把路径计数放大;规定是否允许回到已访问节点,避免循环图导致无界遍历。图模式只负责关系表达,敏感字段仍沿用数据集权限、列级策略和审计规则。
4. 设计可复算的双跑基准
选择代表性的快照和查询族:单跳邻居、两跳转账、带时间过滤的路径、重复边和无结果样例。递归 SQL 与 GQL 输出统一投影到节点 ID、边 ID、路径长度和聚合值,再比较集合和计数。记录 bytes processed、slot 使用、p50/p95 延迟、失败率与结果新鲜度;不要只比较一次墙钟时间。
snapshot = freeze_partition(as_of)
expected = run_recursive_sql(snapshot, query_family)
candidate = run_gql_graph(snapshot, query_family)
assert canonicalize(expected) == canonicalize(candidate)
gate = error_rate < 0.01 and p95_ms <= budget and cost_per_query <= limit5. 处理 Graph 与 SQL 的互操作
需要继续接入报表时,把图查询结果投影成表,再与 SQL 聚合或维度表结合;需要复用同一份关系数据时,避免复制节点和边。Google 文档说明图查询可通过 GRAPH_TABLE 与 SQL 查询组合,因此迁移可以按查询族切分,而不是一次重写所有数据管道。
6. 评估 Preview、成本和回退
Preview 功能要单独记录可用区域、版本、配额和支持边界。先让 SQL 作为主路径,Graph 做影子执行;只有结果一致、成本在预算内、权限和监控齐全时,才按查询族开启。任何 schema 漂移、结果差异、配额错误或成本异常都回退到 SQL,并保留快照、查询文本和执行指标。
高质量示范回答
我会先区分查询形状。固定深度、固定列和简单聚合的报表继续使用递归 SQL,减少 Preview 依赖和迁移成本;需要可变深度、路径模式、节点和边同时返回的探索型分析,才评估 BigQuery Graph。建模时把客户和账户建成节点,把拥有和转账建成有方向的边,并固定主键、方向、时间有效期和循环规则。迁移采用同一快照双跑:把 GQL 与递归 SQL 结果规范化到相同的节点、边、路径长度和指标,再比较结果、扫描量、p95、失败率和成本。SQL 先作为主路径,Graph 影子执行;Preview 的区域、配额或版本发生变化,或任一闸门失败,就回退 SQL。这样回答同时覆盖表达能力、治理、成本和回滚,而不是只宣称图查询更快。
常见错误
- 看到多表 JOIN 就立刻换图 → 固定深度的聚合未必需要图模型 → 先按查询形状分流。
- 只比较一条查询的延迟 → 缓存、快照和数据倾斜会制造偶然结果 → 使用查询族和固定快照比较。
- 忽略重复边和循环 → 路径计数可能被放大或无法终止 → 定义主键、访问规则和最大深度。
- 把 Graph Preview 当作稳定依赖 → 区域、配额和语义可能变化 → SQL 主路径、影子执行和回退闸门。
- 迁移时复制一份图数据 → 双份数据带来新鲜度和治理分叉 → 优先复用同一数据源并投影结果。
追问及应对
如果查询深度从两跳变成任意深度,决定会改变吗?
会。任意深度和路径条件会提高递归 SQL 的维护与资源风险,Graph 的路径表达更合适;仍要设置最大深度、节点访问上限和成本闸门,不能接受无界遍历。
如果业务要求一秒内返回在线结果怎么办?
先确认 BigQuery 批量分析是否满足时延。若不满足,保留在线图存储或预计算索引,BigQuery Graph 用于批量校验和历史分析;不要为了统一语言牺牲在线 SLO。
如何证明 GQL 与递归 SQL 结果一致?
冻结同一分区快照,使用查询族覆盖空结果、重复边、时间边界和循环,再将输出规范化为稳定键和聚合值比较。差异必须保留最小样例、查询版本和数据快照。
什么时候可以移除 SQL 回退?
Preview 状态、区域和客户端兼容性稳定,连续多个数据周期通过结果、成本、延迟、权限和故障演练闸门后,再由数据负责人批准;否则保留 SQL。
图模式包含敏感关系时,权限怎么继承?
沿用数据集、列级和行级策略,并在图查询结果投影处再次检查可见字段。节点或边的可达性本身可能泄露关系,必须把路径暴露纳入审计样例。