天天看點

【SQL學習】——第一部分:SQL基礎

1. 為什麼學習SQL

自人類社會形成之日起,社會的運轉就在不斷地産生和使用各種資訊(文獻、檔案、資料、資料等);在如今所謂的資訊時代,由于計算機和網際網路的作用,資訊的産生和使用達到前所未有的廣度和深度。如何管好和用好資訊,是(而且将一直是)IT行業一塊重要的領域。 在過去幾十年中,關系資料庫一直在這一領域占主導地位,而建立在關系理論基礎之上的SQL也成為資料庫領域的既定标準。

目前的資料存儲領域可稱為三分天下: a. 少量資料的存儲: 自定義資料檔案或通用資料檔案(單機資料庫),通過自定義接口或通用API通路資料。如需要存儲資料的單機軟體或小型的動态網站。 b. 對一緻性要求高的大量資料的存儲: 關系資料庫管理系統(RDBMS)。如各種傳統的資訊系統(ERP、CRM、HRMS、MIS等)。 c. 對并發性要求高的大量資料的存儲: NoSQL資料庫系統。如Web2.0網站的背景資料系統。

以上,“狐假虎威”地借資料存儲的重要性來闡述了一番學習SQL的偉大意義。但重要的是,對SQL善于做什麼和不善于做什麼有個清楚的認識。

2. 學習SQL的參考資料

不久前整理了資料庫圖書ABC一文,對資料庫相關的參考資料作了粗略的分類。

對于初學者而言,可以結合着《資料庫系統概念(第5版)》一書和某個DBMS平台的入門技術手冊練習,自行尋找或構思一個小需求,建一個資料庫,建立幾個表和視圖,練習寫查詢和修改語句。基礎理論和技術實踐可以互相促進。

3. 幾組基本概念

3.1. 單機資料庫與伺服器級資料庫

單機資料庫(如sqlite、Access等,Excel也勉強可以算是)是應用于單個計算機的資料庫引擎,通常不具備網絡連接配接功能,适用于小型應用;程式部署時,一般隻需要附帶資料檔案即可。有時也稱作桌面資料庫。 伺服器級資料庫(如Oracle、DB2、SQL Server、MySQL、PostgreSQL等)是具備網絡連接配接功能、可作為單獨資料庫伺服器的DBMS,适用于大型資訊系統;程式部署時,需要專門安裝相應的DBMS,甚至要單獨進行資料庫伺服器的架構設計。此類資料庫是我們讨論的重點。

3.2. 伺服器(Server)與用戶端(Client)

資料庫伺服器是運作在一台主機(Host)(或主機叢集)上的服務程式,維護着一個或多個資料庫,并通過網絡連接配接響應資料庫用戶端送出的SQL語句。 資料庫用戶端是向資料庫伺服器發送查詢請求的應用程式,可能是DBMS的GUI管理界面或指令行應用程式,也可能是前端的Web伺服器。資料庫用戶端和資料庫伺服器可能是在同一台主機上,但更多情況下則是位于不同的主機上,通過區域網路通路。

例如對于SQL Server來說,一個伺服器執行個體(Instance)即是一個資料庫伺服器,一台主機上可以安裝多個伺服器執行個體;而查詢分析器或SSMS、sqlcmd、以及連接配接資料庫伺服器的IIS,都是資料庫用戶端。

比如你在SSMS中備份/還原/附加一個資料庫,或是通過xp_cmdshell執行一個指令程式,所操作的都是你所連接配接的資料庫伺服器所在主機的檔案,而不是你運作SSMS資料庫用戶端所在主機的檔案。

一台主機有時候會被稱作一台(作業系統)伺服器,而資料庫伺服器和Web伺服器都是運作在主機之上的應用伺服器。它們都被稱作伺服器,不要是以搞混了。

一個典型的基于SQL Server的網站系統的架構示例如下: 使用者浏覽器(Web Client) <----> IIS(Web Server/DB Client) <----> SQL Server(DB Server)

3.3. 資料庫(DB)與資料庫管理系統(DBMS)

“資料庫”這個詞已經被濫用,可能用來指一個資料系統(如中國移動的号碼資料庫),可能用來指一種資料存儲技術(如關系資料庫和NoSQL資料庫),還可能用來指DBMS(如人們常說SQL Server是資料庫軟體)。這種混亂已然形成,恐怕難以改變(比如上文的描述即是如此)。我們隻能根據上下文來判斷具體含義。 按最狹義的技術含義,資料庫(Database)是指位于一個資料庫伺服器執行個體上的一個庫,而DBMS則是指類似SQL Server、Oracle等等此類軟體。初學者要注意這些概念之間的差别。論壇上常常見到這樣的文章:“連不上資料庫”、“資料庫打不開了”,又沒有上下文,可見發問者概念混亂,搞得解答者也是一頭霧水。

3.4. SQL與SQL方言(dialect)

SQL是一個關系資料庫查詢語言的标準,而SQL方言則是各種DBMS在SQL标準上進行的擴充,如增加新的關鍵字、查詢功能、特有的資料類型、支援過程化的控制流語句等。例如SQL Server的T-SQL和Oracle的PL/SQL都是常見的SQL方言。 這就好比ANSI C标準與各種編譯器實作的C語言的差别。但不同SQL方言之間的差異遠大于不同C編譯器之間的差異。SQL方言之間的差異,對于跨DBMS的學習和開發,都是必須注意的。

3.5. 語句、表達式和斷言

語句(statement)是SQL中一個可以單獨執行的單元。如SELECT * FROM table;即是一個語句,其中包含了SELECT子句(clause)和FROM子句。SQL标準規定用分号作為語句的結束,但在目前的T-SQL中,語句結束的分号是可選的。

表達式(expression)是SQL中的一個值(可能是變量、常量、查詢字段或計算結果),對應一種特定的資料類型。SQL中的表達式分為标量表達式和表值表達式,其中表值表達式作為單獨語句則是SELECT語句,作為語句的一部分則稱為子查詢。比如0, col + 2, DATEADD(second, 30, GETDATE())都是(标量)表達式。

需要特别說明的是,SQL中的CASE WHEN是标題表達式,而不是條件語句。比如CASE WHEN中可以使用表達式,卻不能使用語句;CASE WHEN的結果是一個特定資料類型的标量值;CASE WHEN可以用在SELECT、GROUP BY或ORDER BY子句中,但IF ELSE則不行。

斷言(predicate)是SQL中進行比較的結果,即真值,可了解為布爾表達式,因為SQL中沒有bool資料類型,是以将斷言特别從表達式中區分出來。比如1是一個标量表達式,而1 = 1則是一個斷言,後者可以用在WHERE、ON、HAVING、CHECK等需要真值條件的地方,但前者則不可以。由于NULL的存在,SQL中的斷言是三值邏輯,即True/False/Unknown,詳見下文“NULL與三值邏輯”。

下文中多次用到計算和比較兩個詞。表達式和表達式進行計算,結果是新的表達式;表達式和表達式進行比較,結果是一個斷言;斷言和斷言可以進行邏輯運作(AND/OR/NOT),結果是新的斷言。注意其中的差別。

4. SQL不同于一般程式設計語言的地方

4.1. SQL操作的是資料

SQL是資料庫的查詢語言,因而可以對系統資料産生持久化影響。在正常程式設計中,一個錯誤通常隻會造成程式的crash或bug,修改并重新調試往往就可以了;而在SQL中,一個不小心就可能造成系統資料的破壞和丢失。常常有新手執行SQL時,不小心遺漏了DELETE或UPDATE語句中的WHERE子句,這往往是很大的麻煩。

是以,學習和使用SQL,一開始應該養成兩個習慣: 1. 細心。在執行SQL語句認真檢查一下,要清楚自己在做什麼。 2. 及時備份,并考慮對系統的中繼資料進行版本控制。為偶爾的意外準備好後悔藥。

常見的可能造成破壞性影響的SQL關鍵詞:DELETE, UPDATE, DROP, TRUNCATE TABLE。

4.2. SQL是基于集合的說明式語言

SQL擅長集合操作,而不是循環。所謂說明式語言,你隻需要告訴SQL需要做什麼,而不是怎麼做。

初學SQL的人,思維往往難免帶有過程式語言的痕迹,解決問題時常常不由地考慮循環。在學習SQL程式設計時,每當想要用循環時,先反問一下自己:這個問題是不是必須用循環來解決?事實上,多數情況下,這個問題的答案是否定的。

有本書中講,SQL代碼中出現一次IF便要減一些分(比如-1),出現一次WHILE便要減很多分(比如-10或-50,不誇張)。可以嘗試用這樣的方法為自己的存儲過程打分。

5. SQL的三個子集

SQL從功能上可以劃分為三個子集:

1. DML(Data Manipulation Language): 資料操縱語言,是對資料進行查詢和修改(增、删、改)操作的語言。 包含語句:SELECT+INSERT/DELETE/UPDATE 使用對象:DB User

2. DDL(Data Definition Language): 資料定義語言,是對域(資料類型)和關系(表)及其它資料庫對象進行定義的語言。 包含語句:CREATE/DROP/ALTER 使用對象:DB Designer/Developer

3. DCL(Data Control Language): 資料控制語言:是對資料的通路進行權限控制的語言。 包含語句:GRANT/DENY/REVOKE 使用對象:DBA

補充說明: - 嚴格地說,DML隻包含對資料進行修改的語句(INSERT/DELETE/UPDATE),但SELECT語句與DML關系緊密、形式類似,故通常放在一起。既可以統稱為DML,也可以并稱為Query+DML。 - 以上三個子集不包含BACKUP/RESTORE語句。