跳到主要内容
  1. Skills/
  2. thinking in SQL | 废话SQL,思维与实践/

如何看懂SQL文档中的语法图

··字数 1895·4 分钟
sql 概念

学习SQL,不可避免的要查阅数据库产品的SQL手册,它仅仅是数据库文档的一小部分,其它还有数据库编程开发文档,数据库管理维护文档等。而SQL手册文档中,最重要的是语法说明、各种可用函数列表等。语法手册中,通过语法标记或语法图的方式来详解语法。那么,如何看懂这类语法说明,就变成非常重要的基础能力。

SQL,是一种计算机程序可解释、开发者阅读友好的专业领域描述语言(DSL)。为了避免陷入编译原理的深坑,有悟尽量点到为止。

简单科普,为了让计算机程序可解释,语言就需要一定的词法(lexing)规则、语法(syntax)语法规则,根据这些规则,才能编写出解释程序,更进一步转译成可执行程序。计算机基础科学中,有一个理论学科 –《编译原理》,专门研究程序语言设计、程序编译、编译器等领域的问题,很深,慎入。

如果你可以看懂以下几个语法说明,那么本文对你没有帮助。

SQL语言手册中出现的语法说明,是语言设计中的一种语法标记符号范式,有些数据库产品为了可读性,还将这些标记符号转为图形语法图。这些符号范式为 BNF 或 扩展的 BNF

巴科斯范式(英语:Backus Normal Form,缩写为 BNF),又称为巴科斯-诺尔范式(英语:Backus-Naur Form,缩写同样为 BNF,也译为巴科斯-瑙尔范式、巴克斯-诺尔范式),是一种用于表示上下文无关文法的语言,上下文无关文法描述了一类形式语言。它是由约翰·巴科斯(John Backus)和彼得·诺尔(Peter Naur)首先引入的用来描述计算机语言语法的符号集。

– 来自维基百科 《巴科斯范式》

BNF #

BNF 范式,如 rule_name := statement; statement := ...。类似于数学表达式,每一个定义称为一个规则,规则的左边是规则名称,右边是规则内容。定义规则内容时,还有以下这些特殊符号或约束来表达“可选”、“选择”、“选择项”、“结束符”等。

oracle 数据库中的 BNF约定, 原文链接

符号或约定 意义
[ ] 括号内的部分为可选。
{ } 从大括号内的项目中选择一项,不可缺少。
| 可选[]、必选{} 内的备选方案,类似于正则表达式的选择符
表示前面的句法元素可以重复。
分隔符 必须按所示输入除括号、大括号、竖线和省略号之外的分隔符。

有了这些约定,就可以读懂SQL文档的语法说明。

如 oracle 中查询的 选择列表 select-list BNF,

{ *
| { query_name.*
  | [ schema. ] { table | view | materialized view } .*
  | t_alias.*
  | expr [ [ AS ] c_alias ]
  }
    [, { query_name.*
       | [ schema. ] { table | view | materialized view } .*
       | t_alias.*
       | expr [ [ AS ] c_alias ]
       }
    ]...
}

上面BNF所描述的,选择列表可以是 *查询名.*表名.*视图名.*表别名.*,也可以为列定义别名 [[as ] c_alias];如果不是使用 *的,选择列表可以包含多个列。oracle 使用非常严格的 BNF 来编写语法,严格到影响可读性(不排除是为了生成SQL parser)。

比较 mysql 8 的SQL文档中 select 语句 的语法描述。

图形化 BNF #

oracle 数据库、sqlite 数据库,提供了图形化的语法图(graphic syntax diagram),这种图形还有一个形象的名字,叫 railroad diagram(铁路图),它可以将 BNF 语法规则通过图形化的方式表示出来,更易于阅读。

oracle 的 railroad 图全部是图片,没有透露使用什么工具制作。而sqlite的作者,秉持开源的传统,公开他制作 railroad 图的秘密(多才多艺),还将该工具跟sqlite的源码打包在一起开源。

接触过编译原理的都知道,语法图实际是上有限状态图(编译器之所以能实现的重要理论基础)。把一个语法看成一个规则,每一个规则就是图上的一条路线。沿着线跟着箭头走,所穿过的圆角状规则名,进入该规则内部,规则执行完之后,跟着箭头跳出规则,回到原来的层次;或沿着箭头方向,遇到分叉时,根据后续碰到的标记(TOKEN)来判断要走哪一边(对应我们写SQL时,可能出现的多种语法)。这个过程跟普通语言解析器程序进行语法分析的过程是一致的。

语法规则并不是从 1 到 n 顺序排列,而是有分支选择、有可选必选、多层次嵌套,语法文档也是分段说明的,所以阅读手册时要小心,邻近的语法图是否位于同一层次,还是嵌套层次。当习惯了语法图以后,基本可以做到“拿着手册写SQL,不用再上网抄例子了”。

oracle sql 选择列表 select-list
oracle sql 选择列表 select-list
sqlite select语句
sqlite select语句

延伸 #

如果你被 railroad 图的外形有所吸引,有悟再放几个链接。

在线 railroad 语法图生成器 #

语法图鉴赏 #

除了 oracle、sqlite 文档中的 railroad 语法图外,有悟特地找了几幅其它的 railroad 让大家欣赏。