春眠不覺(jué)曉,SQL 知多少?
作者: 不剪發(fā)的Tony老師
畢業(yè)于北京航空航天大學(xué),十多年數(shù)據(jù)庫(kù)管理與開發(fā)經(jīng)驗(yàn),目前在一家全球性的金融公司從事數(shù)據(jù)庫(kù)架構(gòu)設(shè)計(jì)。CSDN學(xué)院簽約講師以及GitChat專欄作者。csdn上的博客收藏于以下地址:https://tonydong.blog.csdn.net
sql
文章目錄
SQL 的誕生
SQL 標(biāo)準(zhǔn)化
SQL:2019
SQL:2016
SQL:2011
SQL:2008
SQL:2006
SQL:2003
SQL:1999
SQL-92
語(yǔ)言特性
語(yǔ)句分類
SQL 實(shí)現(xiàn)
NewSQL
SQL 的誕生
一九七零年,那是一個(gè)夏天。
有一位來(lái)自 IBM 圣約瑟研究實(shí)驗(yàn)室的高級(jí)研究員 Edgar Frank Codd 在 Communications of ACM
上發(fā)表了名為《A Relational Model of Data for Large Shared Data
Banks》的文章,從而創(chuàng)建了關(guān)系數(shù)據(jù)模型。時(shí)至今日,基于該模型的關(guān)系數(shù)據(jù)庫(kù)仍然是數(shù)據(jù)庫(kù)領(lǐng)域的主流;數(shù)據(jù)庫(kù)排名網(wǎng)站 DB-Engines
給出了各類數(shù)據(jù)庫(kù)的排名。
Codd 也因此在 1981 年獲得了計(jì)算機(jī)領(lǐng)域最高獎(jiǎng)圖靈獎(jiǎng),被人們稱為關(guān)系數(shù)據(jù)庫(kù)之父。
1974 年,同樣是來(lái)自 IBM 的 Donald D. Chamberlin 和 Raymond F. Boyce 基于關(guān)系模型開發(fā)了 SQL 的初始版本:SEQUEL(Structured English Query Language)。SEQUEL 被設(shè)計(jì)用于 IBM 最初的準(zhǔn)關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng) SystemR。IBM 隨后基于其 SystemR 原型開發(fā)商業(yè)產(chǎn)品,分別于 1979 年、1981 年和 1983 年上市了 system/38、SQL/DS 和 DB2 數(shù)據(jù)庫(kù)管理系統(tǒng)。
不過(guò)早在 1979 年 6 月,Relational Software,Inc.(現(xiàn)在的 Oracle 公司)發(fā)現(xiàn)了關(guān)系模型的潛力,開發(fā)出了第一個(gè)商用 SQL 實(shí)現(xiàn):Oracle V2(Version2)。隨著收購(gòu)開源數(shù)據(jù)庫(kù) MySQL,Oracle 公司已經(jīng)牢牢占據(jù)了數(shù)據(jù)庫(kù)市場(chǎng)的領(lǐng)先地位,同時(shí)也導(dǎo)致了 MariaDB 分支的出現(xiàn)。
SQL 是關(guān)系模式的第一個(gè)商業(yè)實(shí)現(xiàn),同時(shí)也是最成功的一個(gè)實(shí)現(xiàn)。SQL 是使用最廣泛的數(shù)據(jù)庫(kù)查詢語(yǔ)言。
SQL 標(biāo)準(zhǔn)化
時(shí)間來(lái)到了 1986 年,美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì)(ANSI)首先發(fā)布了 SQL 標(biāo)準(zhǔn);隨后 ISO 標(biāo)準(zhǔn)組織于 1987 年創(chuàng)建了“數(shù)據(jù)庫(kù)語(yǔ)言 SQL”標(biāo)準(zhǔn)。在經(jīng)歷了 1989、1992、1996、1999、2003、2006、2008、2011、2016 以及 2019 年的多次修訂之后,如今的 SQL 標(biāo)準(zhǔn)包含了大量的功能,內(nèi)容多達(dá)數(shù)千頁(yè)。
目前,ISO 組織正則定制第 16 部分,屬性圖查詢(SQL/PGQ)。此前,Neo4j 于 2019 年 9 月 17 宣布圖形查詢語(yǔ)言(GQL)成為了繼 SQL 之后另一種新的 ISO 標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)查詢語(yǔ)言。
新的第 16 部分(SQL/PGQ)主要是為了在 SQL 中直接提供一些 GQL 功能。
SQL:2019
目前最新的 SQL 標(biāo)準(zhǔn)是 SQL:2019,增加了第 15 部分:ISO/IEC 9075-15:2019 多維數(shù)組(SQL/MDA)。SQL/MDA 允許存儲(chǔ)、訪問(wèn)和處理規(guī)模的多維數(shù)組,例如 N 通道的衛(wèi)星圖像。這意味著 SQL 現(xiàn)在可以解碼圖像,并且通過(guò)像素坐標(biāo)直接訪問(wèn)和處理圖像區(qū)域。
以下是當(dāng)前 SQL 標(biāo)準(zhǔn)的組成部分,其中有一些編號(hào)被棄用:
ISO/IEC 9075-1 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 1 部分:框架(SQL/框架)
ISO/IEC 9075-2 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 2 部分:基本原則(SQL/基本原則)
ISO/IEC 9075-3 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 3 部分:調(diào)用級(jí)接口(SQL/CLI)
ISO/IEC 9075-4 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 4 部分:持久存儲(chǔ)模塊(SQL/PSM)
ISO/IEC 9075-9 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 9 部分:外部數(shù)據(jù)管理(SQL/MED)
ISO/IEC 9075-10 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第10 部分:對(duì)象語(yǔ)言綁定(SQL/OLB)
ISO/IEC 9075-11 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 11 部分:信息與定義概要(SQL/Schemata)
ISO/IEC 9075-13 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 13 部分:使用 Java 編程語(yǔ)言的 SQL 程序與類型(SQL/JRT)
ISO/IEC 9075-14 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 14 部分:XML 相關(guān)規(guī)范(SQL/XML)
ISO/IEC 9075-15 信息技術(shù) – 數(shù)據(jù)庫(kù)語(yǔ)言 – SQL – 第 15 部分:多維數(shù)組(SQL/MDA)
ISO 組織提供了一些相關(guān)的技術(shù)報(bào)告。
SQL:2016
SQL:2016 增加了 44 個(gè)可選的新特性,其中 22 個(gè)與 JSON 功能相關(guān),10 多個(gè)與多態(tài)表函數(shù)相關(guān)。
JSON:創(chuàng)建 JSON 文檔、訪問(wèn) JSON 文檔節(jié)點(diǎn)以及 JSON 格式驗(yàn)證的函數(shù)。
行模式識(shí)別:通過(guò) MATCH_RECOGNIZE 子句指定一個(gè)跨行匹配的模式(正則表達(dá)式),同時(shí)可以對(duì)這些匹配的行組進(jìn)行過(guò)濾、分組和聚合操作。行模式識(shí)別可以用于分析數(shù)據(jù)流或者時(shí)間序列數(shù)據(jù),例如股票行情或事件日志。
日期和時(shí)間的格式化與解析。
LISTAGG 函數(shù):可以將多行數(shù)據(jù)轉(zhuǎn)換成指定分隔符的字符串。
多態(tài)表函數(shù):不需要預(yù)先定義返回類型的表函數(shù),允許開發(fā)人員利用動(dòng)態(tài) SQL 創(chuàng)建強(qiáng)大而復(fù)雜的自定義函數(shù)。
新的數(shù)據(jù)類型 DECFLOAT。
這篇文章詳細(xì)介紹了 SQL:2016 的新功能。
SQL:2011
SQL:2011 最主要的新功能之一就是增強(qiáng)了對(duì)時(shí)態(tài)數(shù)據(jù)庫(kù)的支持,具體包括:
時(shí)段定義:使用兩個(gè)標(biāo)準(zhǔn)的字段作為一個(gè)時(shí)段的開始和結(jié)束,包含開始時(shí)間點(diǎn)、不包含結(jié)束時(shí)間點(diǎn)。這種方式與已有的數(shù)據(jù)模型、應(yīng)用程序以及工具一致。
使用 PERIOD FOR 定義應(yīng)用程序時(shí)段表(也稱為有效時(shí)間表)。
使用自動(dòng)時(shí)段拆分更新和刪除應(yīng)用程序的時(shí)間數(shù)據(jù)行。
通過(guò) WITHOUT OVERLAPS 子句為應(yīng)用程序時(shí)間段增加可選的非重疊約束,構(gòu)成時(shí)態(tài)主鍵。
支持應(yīng)用程序時(shí)間表的時(shí)間引用完整性約束。
使用常規(guī)查詢語(yǔ)法或者為時(shí)段數(shù)據(jù)定義的新的時(shí)態(tài)謂詞查詢應(yīng)用程序時(shí)間表,包括 CONTAINS、OVERLAPS、EQUALS、PRECEDES、SUCCEEDS、IMMEDIATELY PRECEDES、IMMEDIATELY SUCCEEDS。
使用 PERIOD FOR SYSTEM_TIME 和 WITH SYSTEM VERSIONING 選項(xiàng)定義系統(tǒng)版本表(也稱為事務(wù)時(shí)間表)。系統(tǒng)時(shí)間段由數(shù)據(jù)庫(kù)自動(dòng)維護(hù)。系統(tǒng)版本表的約束不要求是時(shí)態(tài)約束,并且只在當(dāng)前的數(shù)據(jù)行上強(qiáng)制執(zhí)行。
使用 AS OF SYSTEM TIME 和 VERSIONS BETWEEN SYSTEM TIME … AND 子句查詢系統(tǒng)時(shí)間表中的時(shí)間切片和順序數(shù)據(jù)。
應(yīng)用程序時(shí)間和系統(tǒng)版本可以一起使用,構(gòu)成雙重時(shí)態(tài)表。
這篇文章介紹了 SQL:2011 的新特性,這個(gè)網(wǎng)站可以下載一些 SQL 標(biāo)準(zhǔn)草稿文件,這里是一篇關(guān)于時(shí)態(tài)數(shù)據(jù)庫(kù)的論文。
SQL:2008
SQL:2008 新增的功能主要包括:
增強(qiáng)了 MERGE 和 DIAGNOSTIC 語(yǔ)句。
支持 TRUNCATE TABLE 語(yǔ)句
CASE 表達(dá)式支持逗號(hào)分隔的 WHEN 子句。
INSTEAD OF 觸發(fā)器。
JOIN 分區(qū)表。
FETCH 子句。
允許游標(biāo)定義之外的 ORDER BY。
支持各種 XQuery 正則表達(dá)式/模式匹配。
派生字段名增強(qiáng)。
SQL:2006
SQL:2006 定義了 SQL 操作 XML 的方式。它定義了在 SQL 數(shù)據(jù)庫(kù)中導(dǎo)入和存儲(chǔ) XML 數(shù)據(jù)、在數(shù)據(jù)庫(kù)中操作 XML
數(shù)據(jù),以及以 XML 形式發(fā)布 XML 和常規(guī) SQL 數(shù)據(jù)的方法。此外,它還允許應(yīng)用程序?qū)⒉樵兣c XQuery 集成到 SQL
代碼中,以便同時(shí)訪問(wèn) SQL 數(shù)據(jù)和 XML 文檔。
SQL:2003
SQL:2003 標(biāo)準(zhǔn)引入的新功能主要包括:
XML 相關(guān)功能(SQL/XML)。
窗口函數(shù)(分析函數(shù))。
序列生成器,用于定義序列(sequence)。
兩種新的字段類型:自動(dòng)生成值(generated always as)和標(biāo)識(shí)列(identity)。
合并語(yǔ)句(MERGE)。
CREATE TABLE 擴(kuò)展,支持“CREATE TABLE AS”和“CREATE TABLE LIKE”。
刪除了 BIT 和 BIT VARYING 數(shù)據(jù)類型。
OLAP 功能擴(kuò)展,支持窗口函數(shù)。
這里是一些關(guān)于 SQL:2003 標(biāo)準(zhǔn)的文檔。
SQL:1999
SQL:1999 增加了大量的新功能,并且將 SQL 標(biāo)準(zhǔn)分為了幾個(gè)部分。
數(shù)據(jù)類型:支持布爾數(shù)據(jù)類型,用戶定義的獨(dú)特類型,用戶定義的結(jié)構(gòu)類型。
通用表表達(dá)式和遞歸查詢。
OLAP 功能:GROUP BY 支持 ROLLUP、CUBE 以及 GROUPING SETS 選項(xiàng)。
基于角色的訪問(wèn)控制,CREATE ROLE 語(yǔ)句。
UNNEST 關(guān)鍵字。
正則表達(dá)式匹配。
觸發(fā)器。
支持過(guò)程或控制流語(yǔ)句。
Java 中使用 SQL(SQL/OLB)以及 SQL 中使用 Java(SQL/JRT)。
這個(gè)網(wǎng)站提供了完整的 SQL:1999 教程。
SQL-92
SQL-92 主要的新增功能包括:
新的數(shù)據(jù)類型:DATE、TIME、TIMESTAMP、INTERVAL、BIT 字符串、VARCHAR 以及 NATIONAL CHARACTER 。
支持除了表示 SQL 語(yǔ)句之外的其他字符集。
新的標(biāo)量運(yùn)算,例如字符串連接和獲取子串、日期和時(shí)間運(yùn)算以及條件語(yǔ)句。
新的集合運(yùn)算,例如 UNION JOIN、NATURAL JOIN、集合的差集以及交集。
CASE 條件表達(dá)式。
支持 ALTER 和 DROP 修改模式定義。
C、Ada 以及 MUMPS 語(yǔ)言綁定。
用戶權(quán)限。
新的完整性檢查,例如 CHECK 約束。
新的 information schema,定義了關(guān)于元數(shù)據(jù)的只讀視圖,例如 SELECT * FROM INFORMATION_SCHEMA.TABLES 可以查看數(shù)據(jù)庫(kù)中的表。
查詢語(yǔ)句的動(dòng)態(tài)執(zhí)行(非預(yù)編譯語(yǔ)句)。
更好地支持遠(yuǎn)程數(shù)據(jù)庫(kù)訪問(wèn)。
臨時(shí)表,CREATE TEMP TABLE 等。
事務(wù)隔離級(jí)別。
通過(guò) CAST (expr AS type) 動(dòng)態(tài)修改數(shù)據(jù)類型。
可移動(dòng)的游標(biāo)。
兼容性標(biāo)識(shí),可以定義與其他 SQL 標(biāo)準(zhǔn)的前向以及后向兼容。
隨后,SQL 標(biāo)準(zhǔn)發(fā)布了兩個(gè)重要的擴(kuò)展:
1995 年的 SQL/CLI(調(diào)用級(jí)接口);
1996 年的 SQL/PSM(存儲(chǔ)過(guò)程)。
這里是一篇 SQL-92 標(biāo)準(zhǔn)的原文。
語(yǔ)言特性
SQL(Structured Query Language)是用于管理關(guān)系型數(shù)據(jù)庫(kù)或者關(guān)系型數(shù)據(jù)流管理系統(tǒng)的專用語(yǔ)言。SQL 是一種聲明式的語(yǔ)言,類似于英語(yǔ)。以下是一個(gè)查詢語(yǔ)句:
– 注釋:查詢員工信息
SELECT emp_name, sex, salary * 12
FROM employee
WHERE emp_id = 1;
SQL 語(yǔ)句由幾個(gè)部分組成:
子句, 它們是 SQL 語(yǔ)句組成部分。上面的示例中有 SELECT、FROM 和 WHERE 三個(gè)子句。
表達(dá)式,結(jié)果可以是一個(gè)標(biāo)量值,也可以是一個(gè)結(jié)果集。salary * 12 就是一個(gè)表達(dá)式。
謂詞,用于指定一個(gè)過(guò)濾條件,通常出現(xiàn)在 WHERE 子句中。emp_id = 1 用于過(guò)濾編號(hào)等于 1 的員工。
常量,指定一個(gè)字面常量值。例如 3.14、‘SQL’ 和 ‘2020-02-26’ 等。
標(biāo)識(shí)符,用于指定數(shù)據(jù)庫(kù)中的對(duì)象,例如表、字段等。示例中的 emp_name、employee 都是標(biāo)識(shí)符。
注釋,使用 -- 開始的行或者 /* */ 之間的內(nèi)容表示注釋。注釋不會(huì)被執(zhí)行,用于幫助我們理解代碼。
分號(hào),表示語(yǔ)句的結(jié)束。
另外,SQL 中一些具有固定意義的單詞被稱為關(guān)鍵字,例如 SELECT、CREATE、BEGIN 等。關(guān)鍵字一般大寫。
SQL 基于關(guān)系代數(shù)與元組關(guān)系演算,表和查詢結(jié)果都是由行(元組)的組成的集合;不同之處在于 SQL中的相同行可以出現(xiàn)多次,并且可以指定查詢結(jié)果的順序(ORDER BY)。
語(yǔ)句分類
SQL 提供的主要功能包括:數(shù)據(jù)定義、數(shù)據(jù)操作、數(shù)據(jù)查詢以及數(shù)據(jù)訪問(wèn)控制等。
數(shù)據(jù)定義語(yǔ)言 DDL,定義數(shù)據(jù)庫(kù)的邏輯結(jié)構(gòu),包括數(shù)據(jù)庫(kù)、表、視圖和索引等。主要的語(yǔ)句有 CREATE、ALTER 和 DROP 等。
數(shù)據(jù)操作語(yǔ)言 DML,包括數(shù)據(jù)的增加(INSERT)、修改(UPDATE)、刪除(DELETE)以及合并(MERGE)。
數(shù)據(jù)查詢語(yǔ)言 DQL,SELECT 語(yǔ)句,用于查詢數(shù)據(jù)。
數(shù)據(jù)控制語(yǔ)言 DCL,對(duì)于控制用戶對(duì)數(shù)據(jù)的訪問(wèn)權(quán)限。包括授權(quán)(GRANT)和撤銷(REVOKE)。
事務(wù)控制語(yǔ)言 TCL,用于管理數(shù)據(jù)庫(kù)事務(wù)。包括 BEGIN 、COMMIT、ROLLBACK 等。
除了這些聲明式的語(yǔ)句之外,SQL 也定義了過(guò)程語(yǔ)言的擴(kuò)展(SQL/PSM),也就是存儲(chǔ)過(guò)程。
SQL 實(shí)現(xiàn)
基于以上 SQL 標(biāo)準(zhǔn),許多廠商和組織實(shí)現(xiàn)了自己的數(shù)據(jù)庫(kù)產(chǎn)品。常見(jiàn)的數(shù)據(jù)庫(kù)產(chǎn)品包括:
Oracle,第一個(gè)商業(yè) SQL 數(shù)據(jù)庫(kù),也是數(shù)據(jù)庫(kù)領(lǐng)域的領(lǐng)導(dǎo)者。Oracle 數(shù)據(jù)庫(kù)支持關(guān)系數(shù)據(jù)、列式、XML、JSON、空間、圖形和非結(jié)構(gòu)化數(shù)據(jù),最新的版本為 Oracle Database 19c。Oracle Database Express Edition 是一個(gè)免費(fèi)版本。
MySQL,最流行的開源關(guān)系數(shù)據(jù)庫(kù)。MySQL 支持關(guān)系數(shù)據(jù)、文檔存儲(chǔ)以及 KV 存儲(chǔ),最新版本為 MySQL 8.0。MySQL 還有一些衍生版本,例如 MariaDB、Percorna Server。
Microsoft SQL Server,Microsoft 的關(guān)系數(shù)據(jù)庫(kù)產(chǎn)品,支持關(guān)系數(shù)據(jù)、文檔和圖形數(shù)據(jù)。最新的版本為 SQL Server 2019,支持 Windows 和 Linux 系統(tǒng)。
PostgreSQL,最先進(jìn)的開源關(guān)系數(shù)據(jù)庫(kù),支持關(guān)系數(shù)據(jù)、文檔和圖形數(shù)據(jù)。最新版本為 PostgreSQL 12.2。
SQLite,最流行的嵌入式數(shù)據(jù)庫(kù)。SQLite 是安裝最多的數(shù)據(jù)庫(kù),最新版本為 SQLite 3.31。
雖然這些數(shù)據(jù)庫(kù)大部分的 SQL 語(yǔ)句相同,但是它們都提供了自己的擴(kuò)展語(yǔ)法和功能;因此,我們通常不能直接將一種數(shù)據(jù)庫(kù)中的代碼遷移到另一種數(shù)據(jù)庫(kù),需要進(jìn)行一些代碼修改。
除此之外,這些數(shù)據(jù)庫(kù)還實(shí)現(xiàn)了自己的存儲(chǔ)過(guò)程,增加了一些編程元素。例如變量定義、控制流語(yǔ)句、異常處理等。
這篇文章列出了 11 種常見(jiàn)數(shù)據(jù)庫(kù)對(duì)于 SQL 的功能實(shí)現(xiàn)和示例,包括 Oracle、PostgreSQL、SQL Server、IBM DB2、MySQL、MariaDB、Firebird、H2、HSQLDB、Derby 以及 SQLite。
NewSQL
除了基于關(guān)系模型的傳統(tǒng)數(shù)據(jù)庫(kù)之外,市場(chǎng)上還出現(xiàn)了許多 NoSQL 數(shù)據(jù)庫(kù)。例如 MongoDB、Redis、Apache Cassandra 等。NoSQL 數(shù)據(jù)庫(kù)提供了更高的可用性和可擴(kuò)展性,通過(guò)放棄強(qiáng)一致性大幅提升性能,并且沒(méi)有固定模式的限制。
但是由于 NoSQL 數(shù)據(jù)庫(kù)不支持事務(wù)的強(qiáng)一致性(ACID),無(wú)法適應(yīng)業(yè)務(wù)關(guān)鍵性的應(yīng)用;而且NoSQL 數(shù)據(jù)庫(kù)不提供 SQL 接口,各種系統(tǒng)使用自己的實(shí)現(xiàn)。
因此,出現(xiàn)了一種新型的數(shù)據(jù)庫(kù) NewSQL。簡(jiǎn)單來(lái)說(shuō),NewSQL = SQL + NoSQL 。NewSQL 即提供了與 NoSQL 相同的可擴(kuò)展性,也保留了關(guān)系數(shù)據(jù)庫(kù)的 ACID 事務(wù)特性和標(biāo)準(zhǔn)的 SQL 接口。
常見(jiàn)的 NewSQL 產(chǎn)品包括:VoltDB、TiDB、MemSQL。