前言
確實,關於SQL的學習資料,各類文檔在網上到處都是。但它們絕大多數的出發點都局限在舊有關系數據庫里,內容近乎千篇一律。而在當今大數據的浪潮下,SQL早就被賦予了新的責任和意義。
本篇中,筆者將結合過去在A公司和T公司大數據部門的學習工作經歷,對傳統SQL語法進行一次回顧性學習。同時,思考這門語言在大數據時代的重要意義。
大數據技術中SQL的作用
SQL的全稱為Structured Query Language,也即結構化查詢語言。關系數據庫中,SQL是用戶使用數據庫的基本手段,它能用於創建數據庫或者關系,能對數據庫中各關系進行增刪改查,還能對數據庫進行維護和管理等等。而隨着分布式計算平台如Hadoop,Spark的興起,SQL的應用范圍發生了較大變化,但它作為數據分析核心的地位,始終沒有動搖。在新的背景下,SQL語言具有以下新的意義:
1. 管理大型分布式數據倉儲系統中的"元倉"
所謂"元倉",可以理解為存放元數據的數據庫。關系數據庫中叫數據字典(data dictionary),而Hadoop平台的數據倉庫工具Hive或Spark平台的Spark SQL則將其稱為metastore。在這類分布式的倉儲系統里,數據計算都是在分布式平台上進行,但其metastore幾乎都是建立在傳統的關系數據庫(如MySQL)上。
那么元數據又是什么?對大數據計算分析平台重要嗎?
舉個例子,筆者之前所在的A公司其雲計算系統可以說是國內業界最強。在該公司的某個巨型大數據離線計算平台的元倉里,主要存放的元數據有各關系的基本信息(表名列名等),數據血緣及調度依賴關系,數據權限關系,數據資產關系 ,數據監控關系等等,如下圖所示:

而基於元倉,還可以開發出類似數據地圖系統,數據資產管理系統,數據質量工程系統等高級數據管理工具供公司各類開發人員使用。關於這些數據在分布式平台的采集、管理屬於一個非常有趣而有挑戰的話題,甚至可能是將來雲計算發展的一個重要趨勢所在。但由於這部分比較多的涉及到商業機密,本文點到為止了。
回到主題,讀者想必對元倉的重要性有了感悟。而元倉又是存放在關系數據庫里,因此要想管理好元倉,你需要熟練掌握SQL。
2. 操作大數據平台完成數據分析任務
了解大數據技術的童鞋想必清楚,Hadoop平台沒有實現數據庫,其核心只在於MapReduce編程框架和Hdfs文件系統。但如果每個計算任務都要寫MR代碼,那是很讓人抓狂的。這點很快就被Apache公司注意到,並針對該問題發布了Hive數據倉庫工具。這個工具提供一種類SQL的語言,用戶能直接使用它進行數據分析,而它則負責將類SQL語言轉化為MR代碼,提交Hadoop平台執行。Hive在Hadoop生態圈中的意義恐怕不是最大也是最大之一,很多公司甚至就單純為了使用Hive而搭建的Hadoop環境。所以為了不糾結於分布式代碼縮減開發成本,你需要熟練掌握SQL。
3. 在線報表展示
再舉個例子,筆者在T公司工作時,在利用大數據分析平台進行數據分析后,最終結果需要提交到在線報表系統以進行可視化展示。但由於數據分析結果的量並不大,同時為了利用關系數據庫強一致性等優勢,數據分析的結果都要先從大數據平台轉入關系數據庫,然后讓報表系統從關系數據庫中取數。所以為了順利高效的在線發布數據分析結果,你需要熟練掌握SQL。
4. 其他
以上部分僅僅是SQL應用的冰山一角。對於從事數據研發的人來說,無論在什么環境框架下,都可能用到這門語言。以致於有些同事將之戲稱為"西闊心經":)。
SQL命令綜述
SQL雖然基礎重要應用廣泛,但學起來卻比較容易。記得以前某人跟我說的,想成為一個特級廚師,基本刀功肯定不能差。那么在接下來學習數據倉庫,數據挖掘,深度學習等"高大上"技術之前,還是先好好鞏固一下"西闊心經"吧。
總的來說,SQL語法可以划分為幾大塊:

1. 數據定義語言DDL:用於具體實現關系,以及關系附帶的一些結構,如索引等;
2. 數據查詢語言DML:用於操作數據庫,包括增刪改查;
3. 數據控制語言DCL:用來幫助實現數據庫的存取控制;
4. 事務控制語言TCL:用於數據庫中的事務管理;
接下來本文將對幾大類的SQL進行講解,采用回顧總結型的講解方式,不會涉及過多細節。
DDL
數據定義語言DDL(Data Definition Language)的組成部分並不多,主要涉及到的關鍵字有:CREATE, ALTER, DROP這三個。
1. CREATE
用於創建數據庫,創建關系表,創建視圖等。需要注意的是在建表的時候除了表本身,還要定義主外鍵約束,以及一些附帶結構,如索引等。
2. ALTER
用於調整數據庫/表/視圖的結構信息。
3. DROP
用於刪除數據庫/表/視圖。要注意刪除的時候必須先刪除外碼所在關系,然后再刪除被外碼參照的主碼的關系。
DML
數據查詢語言DML(Data Manipulation Language)是SQL的主體成分,SQL的編寫工作絕大部分都是在這一塊。該部分知識比較雜而多,故本文選擇從整體角度,以經驗總結的形式進行講解,相關語法細節請讀者查詢有關函數手冊。
總的來說,DML有以下功能(底層項為功能所涉及關鍵字):

1. 基本檢索
SELECT+WHERE+GROUP BY(聚集函數)+HAVING+ORDER BY是最常用的查詢組合,要注意的是如果SELECT搭配了GROUP BY,那么GROUP BY后列也要是SELECT的一部分,這樣查詢結果才能清楚展示數據是按什么分組的。另一方面,如果使用了GROUP BY,那么出現在SELECT后不使用聚集函數的列必須也出現在GROUP BY里否則系統提示異常。新手常會犯這個錯誤,如以下代碼:
SELECT id, name, count(*) GROUP BY id
name列沒有使用聚集函數,且沒有出現在GROUP BY后,因此系統必然提示出錯。
因此請意識到GROUP BY后面跟了什么列,SELECT后面就單寫什么列(不使用聚合函數),出現的其他列則必須使用聚合函數。
此外,HAVING后面跟着的約束對象必須是聚合函數列。雖然感覺是有點重復(聚合函數列寫了兩次),而且WHERE子句和HAVING子句中都不允許使用列別名...但若不滿足這些約束,查詢結果會混亂。
2. 高級檢索
a) 嵌套查詢:嵌套查詢的層數盡量不要太高,否則會影響查詢效率;
b) 連接查詢:注意區分幾種JOIN的不同含義;
c) 集合運算:集合運算的本質在於合並多條能"相融"的SQL語句;
3. 插入語句
插入語句的標准形式是INSERT INTO 表名 VALUES(表內容),沒有外碼的關系要優先執行插入。
4. 更新語句
更新語句的標准形式是UPDATE 表名 SET 列值='XX' WHERE 條件。
5. 刪除語句
刪除語句的標准形式DELETE FROM 表名 WHERE 條件。注意不要和刪除表的命令DROP搞混。
6. 其他關鍵字
沒啥好說的。
DCL & TCL
數據控制語言DCL(Data Control Language)主要是管理數據庫權限,負責數據的安全。最常用的是GRANT和ROVOKE命令。
事務控制語言TCL(Transaction Control Language)則主要面向數據庫的備份和恢復兩大主題,常用命令為COMMIT和ROLLBACK。
小結
SQL的學習並不難,但是如果要在具體環境下寫出高質量的SQL,則未必是一件容易的事情。不論是對於傳統的關系型數據庫,還是分布式倉儲系統如Hive、Spark SQL,SQL的優化都可以再單獨寫一本書了。最好在明確了要長期使用的數據分析平台后,再深入針對性地學習專有SQL。比如選定了用Hive,那么就要狠下功夫研究怎么寫SQL才能避免"數據傾斜"問題。
最后,一個優秀的廚師,基本刀功不會差;一個卓越的數據分析師,SQL功底也不會含糊。
