春眠不觉晓,SQL 知多少?

作者: 不剪发的Tony老师
毕业于北京航空航天大学,十多年数据库管理与开发经验,目前在一家全球性的金融公司从事数据库架构设计。CSDN学院签约讲师以及GitChat专栏作者。csdn上的博客收藏于以下地址:https://tonydong.blog.csdn.net


sql
文章目录

        SQL 的诞生
        SQL 标准化
        SQL:2019
        SQL:2016
        SQL:2011
        SQL:2008
        SQL:2006
        SQL:2003
        SQL:1999
        SQL-92
        语言特性
        语句分类
        SQL 实现
        NewSQL

SQL 的诞生

一九七零年,那是一个夏天。

有一位来自 IBM 圣约瑟研究实验室的高级研究员 Edgar Frank Codd 在 Communications of ACM 上发表了名为《A Relational Model of Data for Large Shared Data Banks》的文章,从而创建了关系数据模型。时至今日,基于该模型的关系数据库仍然是数据库领域的主流;数据库排名网站 DB-Engines 给出了各类数据库的排名。

Codd 也因此在 1981 年获得了计算机领域最高奖图灵奖,被人们称为关系数据库之父。

1974 年,同样是来自 IBM 的 Donald D. Chamberlin 和 Raymond F. Boyce 基于关系模型开发了 SQL 的初始版本:SEQUEL(Structured English Query Language)。SEQUEL 被设计用于 IBM 最初的准关系数据库管理系统 SystemR。IBM 随后基于其 SystemR 原型开发商业产品,分别于 1979 年、1981 年和 1983 年上市了 system/38、SQL/DS 和 DB2 数据库管理系统。

不过早在 1979 年 6 月,Relational Software,Inc.(现在的 Oracle 公司)发现了关系模型的潜力,开发出了第一个商用 SQL 实现:Oracle V2(Version2)。随着收购开源数据库 MySQL,Oracle 公司已经牢牢占据了数据库市场的领先地位,同时也导致了 MariaDB 分支的出现。

SQL 是关系模式的第一个商业实现,同时也是最成功的一个实现。SQL 是使用最广泛的数据库查询语言。
SQL 标准化

时间来到了 1986 年,美国国家标准学会(ANSI)首先发布了 SQL 标准;随后 ISO 标准组织于 1987 年创建了“数据库语言 SQL”标准。在经历了 1989、1992、1996、1999、2003、2006、2008、2011、2016 以及 2019 年的多次修订之后,如今的 SQL 标准包含了大量的功能,内容多达数千页。

目前,ISO 组织正则定制第 16 部分,属性图查询(SQL/PGQ)。此前,Neo4j 于 2019 年 9 月 17 宣布图形查询语言(GQL)成为了继 SQL 之后另一种新的 ISO 标准数据库查询语言。

新的第 16 部分(SQL/PGQ)主要是为了在 SQL 中直接提供一些 GQL 功能。
SQL:2019

目前最新的 SQL 标准是 SQL:2019,增加了第 15 部分:ISO/IEC 9075-15:2019 多维数组(SQL/MDA)。SQL/MDA 允许存储、访问和处理规模的多维数组,例如 N 通道的卫星图像。这意味着 SQL 现在可以解码图像,并且通过像素坐标直接访问和处理图像区域。

以下是当前 SQL 标准的组成部分,其中有一些编号被弃用:

ISO/IEC 9075-1 信息技术 – 数据库语言 – SQL – 第 1 部分:框架(SQL/框架)
ISO/IEC 9075-2 信息技术 – 数据库语言 – SQL – 第 2 部分:基本原则(SQL/基本原则)
ISO/IEC 9075-3 信息技术 – 数据库语言 – SQL – 第 3 部分:调用级接口(SQL/CLI)
ISO/IEC 9075-4 信息技术 – 数据库语言 – SQL – 第 4 部分:持久存储模块(SQL/PSM)
ISO/IEC 9075-9 信息技术 – 数据库语言 – SQL – 第 9 部分:外部数据管理(SQL/MED)
ISO/IEC 9075-10 信息技术 – 数据库语言 – SQL – 第10 部分:对象语言绑定(SQL/OLB)
ISO/IEC 9075-11 信息技术 – 数据库语言 – SQL – 第 11 部分:信息与定义概要(SQL/Schemata)
ISO/IEC 9075-13 信息技术 – 数据库语言 – SQL – 第 13 部分:使用 Java 编程语言的 SQL 程序与类型(SQL/JRT)
ISO/IEC 9075-14 信息技术 – 数据库语言 – SQL – 第 14 部分:XML 相关规范(SQL/XML)
ISO/IEC 9075-15 信息技术 – 数据库语言 – SQL – 第 15 部分:多维数组(SQL/MDA)

ISO 组织提供了一些相关的技术报告。
SQL:2016

SQL:2016 增加了 44 个可选的新特性,其中 22 个与 JSON 功能相关,10 多个与多态表函数相关。

JSON:创建 JSON 文档、访问 JSON 文档节点以及 JSON 格式验证的函数。
行模式识别:通过 MATCH_RECOGNIZE 子句指定一个跨行匹配的模式(正则表达式),同时可以对这些匹配的行组进行过滤、分组和聚合操作。行模式识别可以用于分析数据流或者时间序列数据,例如股票行情或事件日志。
日期和时间的格式化与解析。
LISTAGG 函数:可以将多行数据转换成指定分隔符的字符串。
多态表函数:不需要预先定义返回类型的表函数,允许开发人员利用动态 SQL 创建强大而复杂的自定义函数。
新的数据类型 DECFLOAT。

这篇文章详细介绍了 SQL:2016 的新功能。
SQL:2011

SQL:2011 最主要的新功能之一就是增强了对时态数据库的支持,具体包括:

时段定义:使用两个标准的字段作为一个时段的开始和结束,包含开始时间点、不包含结束时间点。这种方式与已有的数据模型、应用程序以及工具一致。
使用 PERIOD FOR 定义应用程序时段表(也称为有效时间表)。
使用自动时段拆分更新和删除应用程序的时间数据行。
通过 WITHOUT OVERLAPS 子句为应用程序时间段增加可选的非重叠约束,构成时态主键。
支持应用程序时间表的时间引用完整性约束。
使用常规查询语法或者为时段数据定义的新的时态谓词查询应用程序时间表,包括 CONTAINS、OVERLAPS、EQUALS、PRECEDES、SUCCEEDS、IMMEDIATELY PRECEDES、IMMEDIATELY SUCCEEDS。
使用 PERIOD FOR SYSTEM_TIME 和 WITH SYSTEM VERSIONING 选项定义系统版本表(也称为事务时间表)。系统时间段由数据库自动维护。系统版本表的约束不要求是时态约束,并且只在当前的数据行上强制执行。
使用 AS OF SYSTEM TIME 和 VERSIONS BETWEEN SYSTEM TIME … AND 子句查询系统时间表中的时间切片和顺序数据。
应用程序时间和系统版本可以一起使用,构成双重时态表。

这篇文章介绍了 SQL:2011 的新特性,这个网站可以下载一些 SQL 标准草稿文件,这里是一篇关于时态数据库的论文。
SQL:2008

SQL:2008 新增的功能主要包括:

增强了 MERGE 和 DIAGNOSTIC 语句。
支持 TRUNCATE TABLE 语句
CASE 表达式支持逗号分隔的 WHEN 子句。
INSTEAD OF 触发器。
JOIN 分区表。
FETCH 子句。
允许游标定义之外的 ORDER BY。
支持各种 XQuery 正则表达式/模式匹配。
派生字段名增强。

SQL:2006

SQL:2006 定义了 SQL 操作 XML 的方式。它定义了在 SQL 数据库中导入和存储 XML 数据、在数据库中操作 XML 数据,以及以 XML 形式发布 XML 和常规 SQL 数据的方法。此外,它还允许应用程序将查询与 XQuery 集成到 SQL 代码中,以便同时访问 SQL 数据和 XML 文档。
SQL:2003

SQL:2003 标准引入的新功能主要包括:

XML 相关功能(SQL/XML)。
窗口函数(分析函数)。
序列生成器,用于定义序列(sequence)。
两种新的字段类型:自动生成值(generated always as)和标识列(identity)。
合并语句(MERGE)。
CREATE TABLE 扩展,支持“CREATE TABLE AS”和“CREATE TABLE LIKE”。
删除了 BIT 和 BIT VARYING 数据类型。
OLAP 功能扩展,支持窗口函数。

这里是一些关于 SQL:2003 标准的文档。
SQL:1999

SQL:1999 增加了大量的新功能,并且将 SQL 标准分为了几个部分。

数据类型:支持布尔数据类型,用户定义的独特类型,用户定义的结构类型。
通用表表达式和递归查询。
OLAP 功能:GROUP BY 支持 ROLLUP、CUBE 以及 GROUPING SETS 选项。
基于角色的访问控制,CREATE ROLE 语句。
UNNEST 关键字。
正则表达式匹配。
触发器。
支持过程或控制流语句。
Java 中使用 SQL(SQL/OLB)以及 SQL 中使用 Java(SQL/JRT)。

这个网站提供了完整的 SQL:1999 教程。
SQL-92

SQL-92 主要的新增功能包括:

新的数据类型:DATE、TIME、TIMESTAMP、INTERVAL、BIT 字符串、VARCHAR 以及 NATIONAL CHARACTER 。
支持除了表示 SQL 语句之外的其他字符集。
新的标量运算,例如字符串连接和获取子串、日期和时间运算以及条件语句。
新的集合运算,例如 UNION JOIN、NATURAL JOIN、集合的差集以及交集。
CASE 条件表达式。
支持 ALTER 和 DROP 修改模式定义。
C、Ada 以及 MUMPS 语言绑定。
用户权限。
新的完整性检查,例如 CHECK 约束。
新的 information schema,定义了关于元数据的只读视图,例如 SELECT * FROM INFORMATION_SCHEMA.TABLES 可以查看数据库中的表。
查询语句的动态执行(非预编译语句)。
更好地支持远程数据库访问。
临时表,CREATE TEMP TABLE 等。
事务隔离级别。
通过 CAST (expr AS type) 动态修改数据类型。
可移动的游标。
兼容性标识,可以定义与其他 SQL 标准的前向以及后向兼容。

随后,SQL 标准发布了两个重要的扩展:

1995 年的 SQL/CLI(调用级接口);
1996 年的 SQL/PSM(存储过程)。

这里是一篇 SQL-92 标准的原文。
语言特性

SQL(Structured Query Language)是用于管理关系型数据库或者关系型数据流管理系统的专用语言。SQL 是一种声明式的语言,类似于英语。以下是一个查询语句:

– 注释:查询员工信息
SELECT emp_name, sex, salary * 12
FROM employee
WHERE emp_id = 1;

SQL 语句由几个部分组成:

子句, 它们是 SQL 语句组成部分。上面的示例中有 SELECT、FROM 和 WHERE 三个子句。
表达式,结果可以是一个标量值,也可以是一个结果集。salary * 12 就是一个表达式。
谓词,用于指定一个过滤条件,通常出现在 WHERE 子句中。emp_id = 1 用于过滤编号等于 1 的员工。
常量,指定一个字面常量值。例如 3.14、‘SQL’ 和 ‘2020-02-26’ 等。
标识符,用于指定数据库中的对象,例如表、字段等。示例中的 emp_name、employee 都是标识符。
注释,使用 -- 开始的行或者 /* */ 之间的内容表示注释。注释不会被执行,用于帮助我们理解代码。
分号,表示语句的结束。

另外,SQL 中一些具有固定意义的单词被称为关键字,例如 SELECT、CREATE、BEGIN 等。关键字一般大写。

SQL 基于关系代数与元组关系演算,表和查询结果都是由行(元组)的组成的集合;不同之处在于 SQL中的相同行可以出现多次,并且可以指定查询结果的顺序(ORDER BY)。
语句分类

SQL 提供的主要功能包括:数据定义、数据操作、数据查询以及数据访问控制等。

数据定义语言 DDL,定义数据库的逻辑结构,包括数据库、表、视图和索引等。主要的语句有 CREATE、ALTER 和 DROP 等。
数据操作语言 DML,包括数据的增加(INSERT)、修改(UPDATE)、删除(DELETE)以及合并(MERGE)。
数据查询语言 DQL,SELECT 语句,用于查询数据。
数据控制语言 DCL,对于控制用户对数据的访问权限。包括授权(GRANT)和撤销(REVOKE)。
事务控制语言 TCL,用于管理数据库事务。包括 BEGIN 、COMMIT、ROLLBACK 等。

除了这些声明式的语句之外,SQL 也定义了过程语言的扩展(SQL/PSM),也就是存储过程。
SQL 实现

基于以上 SQL 标准,许多厂商和组织实现了自己的数据库产品。常见的数据库产品包括:

Oracle,第一个商业 SQL 数据库,也是数据库领域的领导者。Oracle 数据库支持关系数据、列式、XML、JSON、空间、图形和非结构化数据,最新的版本为 Oracle Database 19c。Oracle Database Express Edition 是一个免费版本。
MySQL,最流行的开源关系数据库。MySQL 支持关系数据、文档存储以及 KV 存储,最新版本为 MySQL 8.0。MySQL 还有一些衍生版本,例如 MariaDB、Percorna Server。
Microsoft SQL Server,Microsoft 的关系数据库产品,支持关系数据、文档和图形数据。最新的版本为 SQL Server 2019,支持 Windows 和 Linux 系统。
PostgreSQL,最先进的开源关系数据库,支持关系数据、文档和图形数据。最新版本为 PostgreSQL 12.2。
SQLite,最流行的嵌入式数据库。SQLite 是安装最多的数据库,最新版本为 SQLite 3.31。

虽然这些数据库大部分的 SQL 语句相同,但是它们都提供了自己的扩展语法和功能;因此,我们通常不能直接将一种数据库中的代码迁移到另一种数据库,需要进行一些代码修改。

除此之外,这些数据库还实现了自己的存储过程,增加了一些编程元素。例如变量定义、控制流语句、异常处理等。
在这里插入图片描述

这篇文章列出了 11 种常见数据库对于 SQL 的功能实现和示例,包括 Oracle、PostgreSQL、SQL Server、IBM DB2、MySQL、MariaDB、Firebird、H2、HSQLDB、Derby 以及 SQLite。
NewSQL

除了基于关系模型的传统数据库之外,市场上还出现了许多 NoSQL 数据库。例如 MongoDB、Redis、Apache Cassandra 等。NoSQL 数据库提供了更高的可用性和可扩展性,通过放弃强一致性大幅提升性能,并且没有固定模式的限制。

但是由于 NoSQL 数据库不支持事务的强一致性(ACID),无法适应业务关键性的应用;而且NoSQL 数据库不提供 SQL 接口,各种系统使用自己的实现。

因此,出现了一种新型的数据库 NewSQL。简单来说,NewSQL = SQL + NoSQL 。NewSQL 即提供了与 NoSQL 相同的可扩展性,也保留了关系数据库的 ACID 事务特性和标准的 SQL 接口。

常见的 NewSQL 产品包括:VoltDB、TiDB、MemSQL。