这些是我根据论文 SQL Has Problems 编写的笔记。我们可以修复它们:SQL 中的 Pipe 语法
TL博士
SQL 长期以来一直是结构化数据处理的主导语言,通过本文,GoogleSQL 团队引入了一种新的管道结构化数据流语法,该语法显著提高了 SQL 的可读性、可扩展性和易用性。
该方法涉及向 SQL 添加管道运算符 (|>),这基本上将复杂的查询分解为多个步骤,使其更易于理解和维护。此语法使操作可以按任意顺序任意组合,从而大大简化了复杂查询并提高了可读性。我发现有趣的三件事是:
- 管道语法,使 SQL 更加线性、可扩展和可读
- “prefix 属性”,该属性允许运行部分查询以查看中间结果,从而帮助调试
- 实验性调试运算符 (
ASSERT
,LOG
,DESCRIBE
)
三件有趣的事情
继续上述 TL博士 的讨论,以下是我在这篇论文中发现的三个有趣的事情,以及关于每个事情的一些快速细节。
注释和快速说明
SQL 是结构化数据处理的事实标准,经受住了 50+ 年的时间考验。Google 提出了对 SQL 的扩展,并引入了管道结构的数据流语法,以提高其可用性和可扩展性。
标准 SQL 的基本问题
SQL 的严格子句 (SELECT ... FROM ... WHERE ... GROUP BY) 不反映实际的数据流,该数据流从子句中的表扫描开始。这种结构还使使用新功能扩展语言的过程复杂化,这种脱节会导致几个问题,例如
- SQL 使用重复子句 (
WHERE
,HAVING
,QUALIFY
)来解决严格的子句顺序 - 许多简单的操作需要子查询,导致代码嵌套深度,难以阅读
- SQL 的结构使跟踪逻辑变得困难,尤其是在大型查询中
- 添加新的查询操作具有挑战性,并且过度依赖保留关键字
管道语法解决方案
在传统 SQL 中,查询通常编写在单个整体语句中。GoogleSQL 的新管道语法支持顺序方法,其中一个操作的输出作为下一个操作的输入“管道化”。这种方法很直观,也与数据的处理方式一致。
使用 GoogleSQL 的管道语法,查询可以将零个或多个管道运算符作为后缀,用“|>”分隔。下面是一个使用管道语法的 SQL 查询的快速示例
SELECT column1, column2
FROM table1
WHERE condition1
|> JOIN table2 ON table1.id = table2.id
|> SELECT column3
|> ORDER BY column3 DESC;
每个管道操作符都是一个一元关系操作,接收一个表作为输入并产生一个表作为输出。SQL中的中间结果是具有一个或多个列和零条或多条记录的表。这种结构确保了可组合性,并允许操作符以任意顺序、任意次数应用。每个管道操作符都是自包含的,仅看到其输入表和参数。这种隔离性使得管道操作符天然具备可组合性。
扩展
管道语法极大地提高了SQL通过表值函数(Table-Valued Functions,TVFs)的可扩展性。CALL
操作符允许直接调用 TVFs,而无需使用嵌套子查询。以下是一个快速示例:
SELECT '<text>' AS input, 7 AS rating
|> CALL ML.PREDICT(MODEL `my_project.nnlm_embedding_model`)
|> CALL ML.PREDICT(MODEL `my_project.imdb_classifier`)
内置运算符扩展
管道语法简化了新增内置操作符的添加。例如,PIVOT 操作符在标准 SQL 中实现得较为笨拙,但在管道语法中成为了一个自然而然的可组合管道操作符:
FROM customer JOIN nation ON c_nationkey = n_nationkey
|> SELECT n_name, c_acctbal AS bal, c_mktsegment
|> PIVOT(SUM(bal) AS bal FOR n_name IN ('PERU', 'KENYA', 'JAPAN'))
实验性调试运算符
GoogleSQL 还引入了利用管道语法的调试运算符
ASSERT
:向 SQL 查询添加断言LOG
:记录中间结果表以进行调试DESCRIBE
:返回中间表的架构信息
对语法灵活性的深入观察
这种新语法的一个好处是它可以灵活地容纳现有的 SQL 操作和潜在的未来扩展。因此,SQL 的现有功能(如复杂连接、子查询和聚合)不会被放弃,并且可以用管道语法表示。
管道语法还以更自然、更易读的方式支持用户定义的函数 (UDF)。当数据转换通常需要 SQL 本身不支持的自定义操作时,此功能至关重要。管道语法的模块化特性确保可以在不中断查询流程的情况下合并这些 UDF。
实施和采用
为了实现这一目标,GoogleSQL 团队将管道语法设计为现有 SQL 语法的扩展,而不是替代品。这允许用户在他们的查询中逐渐采用新语法,而无需从一开始就完全承诺它。
该实现生成与标准 SQL 相同的代数,查询引擎只需最少的工作即可启用该功能。这种方法使管道语法立即成为支持查询引擎的一流功能。
GoogleSQL 将管道语法实现为在多个查询引擎(包括 F1、BigQuery、Spanner 和 Procella)之间共享的可重用组件。此共享语言分析组件允许跨多个引擎启用单个实施。
这里展示的内容是我的笔记和基于论文的解释。您可以访问完整的 paper SQL 有问题。我们可以修复它们: Pipe syntax In SQL . 本文只是我的一些理解,强烈建议您阅原文。文中所有的图及代码都来自论文。