《交互式程序設計 第2版》一導讀
前 言
SQL無所不在。盡管如此,SQL卻難以使用:SQL是複雜的,令人困惑且容易出錯(我敢說比它的衛道士所聲稱的更容易出錯)。所以,為了寫出你能確信的精確SQL代碼(意思是它準確地做到了要求它做的事),你就必須遵從一些適當的準則。而本書的主題就是:關係化地使用SQL,這就是你需要的準則。不過,這到底意味著什麼?難道SQL不是關係化的嗎?
沒錯,SQL確實是用於關係化數據庫的標準語言,但是這個事實本身並不能讓它成為關係化的語言。讓人感到不幸的真相是:SQL在太多的方麵背離了關係理論;重複行和null就是兩個明顯的例子,而它們絕不是僅有的兩個問題。結果就是,可以說SQL語言為你提供了“上吊用的繩子”。所以,如果你不想“上吊”,就需要理解關係理論(是什麼以及為什麼),需要知道SQL對於關係理論的背離之處,還需要知道怎樣避免背離之處所造成的這些問題。總的來說,你需要關係化地使用SQL。這樣,你就能把SQL當作是真正關係化的語言來運用,而且可以享受使用真正的關係係統所帶來的好處。
如果每個人都已經關係化地使用SQL了,就不再需要像本書這樣的書籍了。但問題是,情況並非如此。我看到當前的SQL使用中存在著大量的糟糕實踐,甚至看到有的(本應具有更好認知的)作者在課本或類似出版物中推薦這些糟糕實踐。事實上,對此方麵文獻的回顧是相當令人沮喪的。關係模型誕生於1969年,然而直到40多年後的今天,它似乎還是沒有被數據庫領域中的大多數人所充分理解。所以,本書將關係模型本身作為一個組織原則,其部分原因也來自於此。本書深入講解關係模型的諸多特性,並說明在每種情況下為了遵守這些特性怎樣最好地使用SQL。
預備知識
我假設你是熟悉SQL的數據庫專業技術人員。具體地說,我假設你具有對於SQL標準(或至少是對於一個SQL產品)的工作知識。然而,我並不假設你深入理解關係理論(盡管我確實希望你明白:關係模型是個好東西,並且隻要可能就應堅持關係模型)。所以,我會詳細描述關係模型的各個特性以免誤解。我還會說明怎樣使用SQL去遵守那些特性。不過,我不會證明所有特性;相反,我假設你在數據庫方麵已經具有足夠的經驗,能夠理解為什麼鍵的概念是有意義的,為什麼有時需要做連接,而又為什麼需要支持多對多聯係,等等。(如果要包括這些證明,那麼本書就會大變樣,比現在的厚得多。況且,那樣的書已經有了。)
我說過,我期望你熟悉SQL。雖然如此,我還是會詳細“解釋SQL的某些方麵,尤其是實踐中不常碰到的那些內容。比如,SQL的“可能非確定性表達式”(possibly nondeterministic expression)。參見第12章。
深入數據庫
本書基於並要超越以前的《Database in Depth: Relational Theory for Practitioners》(O'Reilly Media Inc.,2005)一書。在那本書中,我的目標如下(摘自前言):
在數據庫圈子裏工作多年之後,我終於意識到:需要有一本書,用一種未被現存產品、商業實踐或SQL標準的怪癖所汙染的方式為專業人員(而不是新手)解釋關係理論的基本原理。我寫這本書就是為了滿足這個需要。我所期望的讀者是有經驗的數據庫專業人員:他們足夠誠實,勇於承認自己並不理解自身領域所基於的以及自己應該知道的那個理論。“那個理論”所指的當然就是關係模型,盡管該理論的基本思想都非常簡單,但這些思想還是被廣泛地誤傳誤評。事實上,它們似乎就沒被真正理解過。比如,下麵就有一些關係模型的問題,你能回答出多少?注1
1. 第一範式到底是什麼?
2. 關係和謂詞之間的聯係是什麼?
3. 語義優化是什麼?
4. 映像關係是什麼?
5. 為什麼半差(semidifference)重要?
6. 為什麼延遲完整性檢查毫無意義?
7. 關係變量是什麼?
8. 前束範式是什麼?
9. 關係能有一個其取值為關係的屬性嗎?
10. SQL是關係完備的嗎?
11. 為什麼“信息原理”重要?
12. XML怎樣才符合關係模型?
本書對這些問題以及相關問題進行了解答。總的來說,本書就是為了幫助數據庫專業人員去深入理解關係理論,並在日常的專業工作中很好地運用這些對於關係理論的深入認知。
正如這段引文的最後一句所言,我曾經希望本書讀者不需要進一步的協助就能夠自己運用關係理論的思想。不過,我隨後就意識到:與流行觀點恰恰相反,要在不違反關係理論原理的情況下使用SQL這種語言可絕不是一眼就能看出來的事。所以,我決定將先前的書進行擴展,以便包括對於該問題(我指的是怎樣關係化地使用SQL)明確具體的建議。本書的目標仍然和先前的書一致:幫助數據庫專業人員深入理解關係理論並在其日常的專業工作中很好地運用這些對於關係理論的深入認知。不過,我試著讓書中的內容更好消化一些,更容易應用。總之,我收錄了大量與SQL相關的資料(也正因為如此,本書才會比先前的那本書在篇幅上有所增加)。
對正文的進一步說明
我需要進一步說明幾點。第一,我對於關係模型的理解在多年來是不斷演進的,並且還將繼續下去。本書代表了我對該主題的最新思考,所以,如果你發現這本書和我的其他書(尤其是本書所要超越的那本書)之間存在什麼技術上的差異(確實有幾個),請以這本書為準。不過,絕大部分的差異都是相當微小的,而且,我在必要的時刻總會將新的術語及概念和先前的術語及概念聯係起來。
第二,我會講到理論,不過,我的信條是:理論是實用的。之所以我要明確指出此點,是因為有太多的人不這麼認為,即很多人認為理論化的東西是不實用的。但真相是:理論真的是絕對、非常實用的。關係理論的目的不是理論本身,而是讓我們能夠構建完全實用的係統。關係理論中的每個細節都緣自於切實的實用原因。正如Stéphane Faroult(先前那本書的評審者)所寫:“一旦你有了一點實踐,你就會意識到不懂得關係理論是不行的。”而且,關係理論不僅是實用的,而且是基礎的、直截了當的、簡單的、有用的,(正如我希望在本書中證明的那樣)也會是有趣的。
當然,對於前述論題,我們就不必去找比關係模型本身還要更進一步的例證了。實際上,在我們這樣的環境下(即建立在一個偉大的理論思想之上的幾十億美元規模的產業)真的應該不必為“理論是實用的”辯解。不過,我猜某些人的觀點會是“沒錯,但理論為我做了什麼呢?”總之,堅信理論是重要的人們必須不斷地向批評者證明自己,這又是一個我認為需要本書的原因。
第三,前麵提到過,本書會討論相當多的SQL相關特性細節或關係模型細節。(對於和關係化不太相關的主題,本書有意進行了回避。比如,本書中關於事務的內容就不多。)自始至終,我都設法說清楚適用於SQL的討論以及適用於關係模型的討論。不過,我想強調的是:我並不想對SQL進行詳盡全麵的討論。SQL太複雜了(更何況還為做同一個事情提供了太多的不同方法,而且還有那麼多例外和特例),要想詳盡全麵地討論它(我都懷疑是不是真的能做到這點)隻會適得其反;而且,詳盡全麵的討論肯定會增加本書的篇幅。所以,我設法隻關注我所認為的最重要問題,而且盡可能簡短地說明所選擇的問題。我想說,如果你做了我告訴你的每件事,並且不做我沒有告訴你的任何事,那麼你基本上就會是安全的:你就是關係化地使用了SQL。不過,我的說法到底有沒有道理,或者在多大程度上是有道理的必須由你來判斷。
對於前文我還要補充說明的是:很遺憾,有些情況下就是不能關係化地使用SQL。比如,雖然關係模型將延遲完整性檢查作為邏輯錯誤明確拒絕,但有的SQL完整性檢查必須延遲(通常延遲到提交時刻)。盡管本書對在這種情況下如何進行處理給出了建議,但是我擔心最終還是會“盡你的能力做好”。至少,我希望你會理解背離關係模型所帶來的風險。
我還要說的是,本書所給的一些建議也不是特定於關係化的,而隻是關於一般的優秀實踐的——盡管有時會受(不太明顯的)關係化方麵的影響。避免型轉就是這種情況的很好示例。
第四,請記住,除非明確聲明,我在全書中使用的都是標準版本的SQL語言(而不是某些專屬的方言)。尤其是,我和SQL標準一樣假設其發音為“ess cue ell”而不是“sequel”(盡管後者在業界很普遍)。
第五,除非提示,否則本書是要按順序閱讀的(大多數章節都在某種程度上依賴於前麵章節的內容,所以你不應該跳來跳去)。還有,每一章都有一套練習題。當然,不是必須做這些練習,但是我覺得試試某些練習總不是壞事。練習的答案(經常給出相應主題的更多信息)在附錄F中給出。
第六,我有一些基於本書內容的研討會記錄可以使用,其詳細內容參見www.justsql.co.uk/chris_date/chris_date.htm或www.thethirdmanifesto.com。其中一個研討會的在線版本也是可用的,地址是https://oreilly.com/catalog/0636920010005/。
使用代碼示例
本書旨在幫助你完成手頭的工作。一般而言,你可以在自己的程序和文檔中隨意使用本書中的代碼。除非原樣引用大量的代碼,否則你無須征得我們的許可。例如,在編寫程序時引用了本書的若幹代碼片段是無須許可的。而銷售或發行O扲eilly圖書的示例光盤則須要許可。通過引用書中內容及示例代碼的方式答疑解難無須許可,而將書中的大量示例代碼加入到你的產品文檔中則須要許可。
如果你在引用時注明出處(並非必須),我們將不勝感激。引用通常包含書名、作者、出版商及ISBN。例如:“SQL and Relational Theory, Second Edition, by C.J. Date (O扲eilly). Copyright 2012 C.J. Date,9781449316402”。
如果你發現自己對示例代碼的使用有失公允或違反了上述條款,敬請通過permissions@oreilly.com與我們取得聯係。
評論及疑問
如果你想就本書發表評論或有任何疑問,敬請聯係出版社:
美國:
O扲eilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中國:
北京市西城區西直門南大街2號成銘大廈C座807室(100035)
奧萊利技術谘詢(北京)有限公司
我們為本書製作了網頁,列出了勘誤表、示例以及任何附加信息。你可以通過https://shop.oreilly.com/product/0636920022879.do訪問該網頁。
如果你想就本書發表評論或提問技術問題,請發送E-mail至:bookquestions@oreilly.com。
關於我們的書籍、課程、會議以及新聞的更多信息,敬請訪問我們的網站https://www.oreilly.com。
在Facebook上找到我們:https://facebook.com/oreilly.
在Twiiter上關注我們:https://twitter.com/oreillymedia.
在YouTube上觀看我們的視頻:https://www.youtube.com/oreillymedia.
致謝
我一直都想著修訂先前那本書以便包括關於SQL的更多內容,然而直到2007年後期的一次針對數據庫專業人員的授課時才下定決心。那次授課由Toon Koppelaars講課,並且課程基於他和Lex de Haan所寫的書籍(參見本書附錄G),課程進行得也很好。然而,那次授課給我的最大衝擊就是親眼看到參與人員在將關係原理及邏輯原理應用於對於SQL的使用過程中時所麵對的各種困難。現在,我猜那些參與人員已經具有了那些主題的一些知識,畢竟他們是數據庫專業人員。但是我覺得他們在將關係化思想和邏輯思想運用於日常數據庫工作方麵確實需要一些指導。所以,我編寫了這本書。因此,首先我要感謝Toon和Lex為我啟動這個項目提供了必要的動力。我還要感謝對於早期草稿給出評議的評審者Herb Edelstein、Sheeri Ktitzer、Andy Oram、Peter Robson和Baron Schwartz以及給予其他技術協助的Hugh Darwen和Jim Melton。其次,我要一如既往地感謝我的妻子Lindy,感謝她多年來一直支持著我所有的數據庫項目。最後,我要感謝所有在O扲eilly工作的同仁,特別是Isabel Kunkle和Andy Oram,感謝他們對於本書出版的鼓勵、貢獻和支持。
目 錄
第1章 做好準備
1.1 關係模型被嚴重地誤解了
1.2 關於術語的一些說明
1.3 原理而非產品
1.4 原始模型回顧
1.5 模型vs.實現
1.6 關係的性質
1.7 基關係vs.導出關係
1.8 關係vs.關係變量
1.9 值vs.變量
1.10 小結
1.11 練習題
第2章 類型和域
2.1 類型和關係
2.2 相等性比較
2.3 數據值原子性
2.4 類型是什麼
2.5 標量類型vs.非標量類型
2.6 SQL中的標量類型
2.7 SQL中的類型檢查和型轉
2.8 SQL中的字符序
2.9 SQL中的行類型和表類型
2.10 小結
第3章 元組、關係、行、表
3.1 元組是什麼
3.2 SQL中的行
3.3 關係是什麼
3.4 關係及其主體
3.5 關係是n維的
3.6 關係比較
3.7 TABLE_DUM和TABLE_DEE
3.8 teSQL中的表xt
3.9 SQL中的列命名
3.10 小結
第4章 不要重複,不要null
4.1 重複有什麼問題
4.2 重複:深入討論
4.3 在SQL中避免重複
4.4 null有什麼毛病
4.5 在SQL中避免null
4.6 對外連接的說明
4.7 小結
4.8 練習題
第5章 基關係變量和基表
5.1 更新是集合級別的
5.2 關係賦值
5.3 關於候選鍵的更多內容
5.4 關於外鍵的更多內容
5.5 關係變量和謂詞
5.6 關係 vs. 類型
5.7 練習題
第6章 SQL和關係代數I:原始運算符
6.1 一些預備知識
6.2 關於閉包的更多內容
6.3 限製
6.4 投影
6.5 連接
6.6 並、交和差
6.7 哪些運算符是基本運算符
6.8 逐步形成表達式
6.9 關係表達式到底表示什麼
6.10 計算SQL表表達式
6.11 表達式變換
6.12 屬性名依賴
6.13 練習題
第7章 SQL和關係代數II:附加運算符
7.1 排他並
7.2 半連接和半差
7.3 擴展
7.4 映像關係
7.5 除
7.6 聚集運算符
7.7 再議映像關係
7.8 匯總
7.9 再議匯總
7.10 分組、去分組和關係值屬性
7.11“WHAT IF”查詢
7.12 對於遞歸的說明
7.13 ORDER BY是怎麼回事
7.13 練習題
第8章 SQL與約束
8.1 類型約束
8.2 SQL中的類型約束
8.3 數據庫約束
8.4 SQL中的數據庫約束
8.5 事務
8.6 數據庫約束為什麼必須立即檢查
8.7 不是有些檢查必須延遲進行嗎
8.8 約束與謂詞
8.9 各種問題
8.10 練習題
第9章 SQL與視圖
9.1 視圖是關係變量
9.2 視圖和謂詞
9.3 檢索運算
9.4 視圖和約束
9.5 更新運算
9.6 視圖的作用
9.7 視圖和快照
9.8 練習題
第10章 SQL與邏輯
10.1 為什麼需要邏輯
10.2 簡單命題和複合命題
10.3 簡單謂詞和複合謂詞
10.4 量詞化
10.5 關係演算
10.6 關於量詞化的更多內容
10.7 一些等價關係
10.8 小結
10.9 練習題
第11章 使用邏輯表述SQL表達式
11.1 一些變換法則
11.2 例1:邏輯蘊涵
11.3 例2:全稱量詞化
11.4 例3:蘊涵和全稱量詞化
11.5 例4:相關子查詢
11.6 例5:命名子表達式
11.7 例6:關於命名子表達式的更多內容
11.8 例7:處理模煳性
11.9 例8:使用COUNT
11.10 例9:連接查詢
11.11 例10:唯一量詞化
11.12 例11:ALL或ANY比較
11.13 例12:GROUP BY和HAVING
11.14 練習題
第12章 關於SQL的其他主題
12.1 SELECT *
12.2 顯式表
12.3 名稱限定
12.4 區間變元
12.5 子查詢
12.6 “可能非確定性”表達式
12.7 空集合
12.8 簡化的BNF語法
12.9 練習題
附錄A 關係模型
附錄B SQL背離關係模型之處
附錄C 處理信息丟失的關係方法
附錄D Tutorial D語法
附錄E 本書建議匯總
附錄F 練習答案
附錄G 深入閱讀建議
最後更新:2017-07-10 14:02:15