结构化查询语言/SQL:一种用于处理关系型数据库管理系统 (RDBMS) 的语言
如上所述,RDBMS 使用诸如投影、选择、联接、集合运算(并集、差集和交集)等关系代数操作对数据进行操作。关系代数的操作是用一种高度形式化且对最终用户难以理解的数学语言表示的,并且可能也对许多软件工程师难以理解。因此,RDBMS 提供了关系代数之上的一层,这层易于理解,但可以映射到底层的关系操作。自 20 世纪 70 年代以来,我们看到了一些执行此工作的语言;其中之一是 SQL - 另一个例子是QUEL。在 20 世纪 80 年代初(由于商标问题,从其原始名称SEQUEL重命名后),SQL 实现了市场主导地位。1986 年,SQL 首次被标准化。当前版本是SQL 2023。
SQL 的标记和语法是基于英语口语来建模的,以尽可能降低访问门槛。像UPDATE employee SET salary = 2000 WHERE id = 511;
这样的 SQL 命令与句子“将 id 为 511 的员工的薪水更改为 2000”相差不远。
SQL 的关键字可以以任何大小写字符组合表示,即关键字不区分大小写。在 SQL 代码中写UPDATE, update, Update, UpDate
或任何其他大小写组合都没有区别。
接下来,SQL 是一种描述性语言,而不是过程式语言。它没有规定关系操作的所有方面(哪个操作,它们的顺序,...),这些操作是根据给定的 SQL 语句生成的。RDBMS 可以从一个语句中生成多个执行计划。它可以将多个生成的执行计划进行比较,并在给定情况下运行它认为最好的执行计划。此外,程序员无需考虑数据访问的所有细节,例如:如果将一组 WHERE 条件与 AND 组合使用,应该首先评估哪一个条件?
尽管有上述简化,但 SQL 非常强大。它允许使用单个语句对一组数据记录进行操作。UPDATE employee SET salary = salary * 1.1 WHERE salary < 2000;
将影响所有实际薪水低于 2000 的员工记录。可能会有成千上万条这样的记录,也可能只有几条或甚至没有。该操作也可能取决于数据库中已有的数据;语句SET salary = salary * 1.1
导致薪水提高 10%,对于某个员工可能是 120,而对于另一个员工可能是 500。
SQL 的设计者试图正交地定义语言元素。其中包括,任何语言元素都可以在语句的所有位置使用,在这些位置可以使用该元素的结果。例如:如果您有一个函数 power(),它接受两个数字并返回另一个数字,您可以在允许使用数字的所有位置使用此函数。以下语句在语法上是正确的(如果您已定义函数 power())- 并导致相同的输出行。
SELECT salary FROM employee WHERE salary < 2048;
SELECT salary FROM employee WHERE salary < power(2, 11);
SELECT power(salary, 1) FROM employee WHERE salary < 2048;
正交性的另一个例子是在 UPDATE、INSERT、DELETE 中或在另一个 SELECT 语句中使用子查询。
但是,SQL 并非没有冗余。通常有几种可能的表述来表达相同的情况。
SELECT salary FROM employee WHERE salary < 2048;
SELECT salary FROM employee WHERE NOT salary >= 2048;
SELECT salary FROM employee WHERE salary between 0 AND 2048; -- 'BETWEEN' includes edges
这是一个非常简单的例子。在复杂的语句中,可能需要在联接、子查询和exists谓词之间进行选择。
核心 SQL 由语句组成。语句由关键字、运算符、值、系统和用户对象或函数的名称组成。语句以分号结束。在语句SELECT salary FROM employee WHERE id < 100;
中,标记 SELECT、FROM 和 WHERE 是关键字。salary、employee 和 id 是对象名称,“<”符号是运算符,“100”是值。
SQL 标准将语句组织成九组
- “SQL 语句的主要类别是
- SQL 模式语句;这些可能对模式集产生持久影响。
- SQL 数据语句;其中一些,SQL 数据更改语句,可能对 SQL 数据产生持久影响。
- SQL 事务语句;除了 <commit 语句> 外,这些语句以及以下类别,在 SQL 会话终止时不会产生任何持久影响。
- SQL 控制语句。
- SQL 连接语句。
- SQL 会话语句。
- SQL 诊断语句。
- SQL 动态语句。
- SQL 嵌入式异常声明。”
这种详细的分组在日常用语中并不常见。一种典型的替代方法是将 SQL 语句组织成以下几组
- 数据定义语言 (DDL):管理数据库对象的结构(创建/更改/删除表、视图、列,...)。
- 数据查询语言 (DQL):使用 SELECT 语句检索数据。该组只有一个语句。
- 数据操作语言 (DML):使用 INSERT、UPDATE、MERGE、DELETE、COMMIT、ROLLBACK 和 SAVEPOINT 语句更改数据。
- 数据控制语言 (DCL):管理访问权限(授予、撤销)。
如上所述,核心 SQL 并不图灵完备。它缺少条件分支、变量、子例程。但标准以及大多数实现都提供了一种扩展来满足对图灵完备性的需求。在标准的“第 4 部分:持久存储模块 (SQL/PSM)”中,对 IF-、CASE-、LOOP-、赋值和其他语句进行了定义。该部分的现有实现具有不同的名称、不同的语法,以及不同的操作范围:Oracle 中的 PL/SQL,DB2 中的 SQL/PL,SQL Server 和 Sybase 中的 Transact-SQL 或 T-SQL,Postgres 中的 PL/pgSQL 以及 MySQL 中的“存储过程”。