「SQL數據分析系列」1. SQL背景知識介紹

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"寫在前面:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家好,我是強哥,一個熱愛分享的技術狂。目前已有 12 年大數據與AI相關項目經驗, 10 年推薦系統研究及實踐經驗。平時喜歡讀書、暴走和寫作。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業餘時間專注於輸出大數據、AI等相關文章,目前已經輸出了40萬字的推薦系統系列精品文章,今年 6 月底會出版「構建企業級推薦系統:算法、工程實現與案例分析」一書。如果這些文章能夠幫助你快速入門,實現職場升職加薪,我將不勝歡喜。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"想要獲得更多免費學習資料或內推信息,一定要看到文章最後喔。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"內推信息","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你正在看相關的招聘信息,請加我微信:liuq4360,我這裏有很多內推資源等着你,歡迎投遞簡歷。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"免費學習資料","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你想獲得更多免費的學習資料,請關注同名公衆號【數據與智能】,輸入“資料”即可!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"學習交流羣","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你想找到組織,和大家一起學習成長,交流經驗,也可以加入我們的學習成長羣。羣裏有老司機帶你飛,另有小哥哥、小姐姐等你來勾搭!加小姐姐微信:epsila,她會帶你入羣。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"第一章 SQL背景知識","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在我們開始學習本書的內容之前,先回顧一下數據庫技術的歷史,以便更好地瞭解關係數據庫和SQL語言是如何演變的。因此,我會先介紹一些基本的數據庫概念,看看計算機數據存儲和檢索的發展史。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"注意:對於那些急於開始寫查詢語句的讀者,可以直接跳到第三章,但我建議在此之後還是再回到前兩章看看,以便更好地瞭解SQL語言的歷史和實用性。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"數據庫簡介","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據庫指的是一組相關信息的集合。例如,電話簿可以被看做一個數據庫,其中包含某地區所有居民的姓名、電話號碼和地址等信息。雖然電話簿是一個十分普及和常用的數據庫,但是它存在以下問題:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•查找一個人的電話號碼可能很費時,特別是電話簿包含大量條目時;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•電話簿只按姓/名來索引,因此查找居住在特定地址的人的姓名的時候,雖然理論上可行,但對該數據庫來說並不實用;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•從打印電話簿的那一刻起,隨着居民在該地區的流動、更改電話號碼或遷移到同一地區內的另一個地方等動作的發生,電話簿上的信息變得越來越不準確。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"電話簿的上述缺點也在任何手動編制的數據存儲系統上存在,例如存儲在文件櫃中的病歷等。由於這些紙質數據庫很繁瑣,所以最初開發的一些計算機應用程序就是數據庫系統,它通過計算機來存儲和檢索數據。因爲數據庫系統以電子方式而不是紙質方式存儲數據,所以它能夠更快速地檢索數據、以多種方式索引數據並向用戶社區提供最新信息。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"早期的數據庫系統管理存儲在磁帶上的數據。由於磁帶的數量通常要遠遠超過磁帶讀取器,所以技術人員的任務就是在需要特定數據時手動裝卸磁帶。而且由於那個時代的計算機內存非常小,通常情況下對於同一數據的併發請求需要多次讀取磁帶上的數據。儘管這些數據庫系統比紙質數據庫有了顯著的改進,但它們與當今技術所能實現的相差甚遠。(現代數據庫系統可以管理數PB[ 拍字節(Petabytes),計算機存儲容量單位,也常用PB來表示。1PB=1024TB==2^50字節]的數據,由服務器集羣訪問,每個服務器在高速內存中緩存數萬GB[ gb也叫吉字節(GB、Gigabyte,在中國又被稱爲吉咖字節或京字節或十億字節或戟),常簡寫爲G,是一種十進制的信息計量單位。]的數據,不過這些內容可能有些超前了)","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"非關係型數據庫","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"注意:本節包含一些早期非關係型數據庫系統的背景信息。對於渴望深入學習SQL的讀者,可以跳過這幾頁進入下一部分。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"在計算機化數據庫系統的前幾十年中,數據以各種方式存儲和呈現給用戶。例如,在層次數據庫系統中,數據表示爲一個或多個樹結構。如圖(1-1)顯示了George Blake和Sue Smith銀行賬戶的相關數據,它們通過樹結構表示:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/55/551d11ccd908aec59c244825286a57ca.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"George和Sue都有自己的樹結構,包含他們的賬戶以及交易信息。層次數據庫系統提供了定位特定客戶樹的工具,並能遍歷該樹以找到所需的帳戶或交易數據。樹中的每個節點可以有零個或一個父節點,以及零個、一個或多個子節點。這種配置被稱作單根層次結構(single-parent hierarchy)。","attrs":{}}]},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 拍字節(","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"Petabytes","attrs":{}},{"type":"text","text":"),計算機存儲容量單位,也常用PB來表示。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1PB=1024TB==2^50字節","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" gb也叫吉字節(GB、Gigabyte,在中國又被稱爲吉咖字節或京字節或十億字節或戟),常簡寫爲G,是一種十進制的信息計量單位。","attrs":{}}]},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另一種管理數據的方法稱爲網狀數據庫系統,它表現爲多個記錄集合,集合之間通過連接定義不同記錄之間的關係。如圖(1-2)顯示了該系統中George和Sue的賬戶信息:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/68/6823c06d54b3291756a4ad3a6b2a0bbb.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了找到轉移到Sue的貨幣市場賬戶(money market account,MoneyMkt)的交易記錄,需要執行以下步驟:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.查找Sue Smith的客戶記錄;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.根據Sue Smith的客戶記錄鏈接到她的賬戶列表;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3.遍歷賬戶鏈,直到找到貨幣市場賬戶;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4.通過鏈接從貨幣市場記錄找到其交易列表。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上圖(1-2)最右邊的一組產品記錄(Products)展示了網狀數據庫系統的一個有趣特性。請注意,每個產品記錄(Checking、Savings等)都指向該產品類型的帳戶記錄列表。因此,可以從多個位置(客戶記錄和產品記錄)訪問帳戶記錄,這使得網狀數據庫具備多層次結構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"層次數據庫系統和網狀數據庫系統如今仍然存在,不過通常在大型機領域中使用。此外,層次數據庫系統在目錄服務領域有了新的應用,比如微軟的Active Directory和開源Apache目錄服務器。然而,從20世紀70年代開始,一種新的表示數據的方法開始生根發芽,這種方法更加嚴謹,並且易於理解和實現。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"關係模型","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1970年,IBM研究實驗室的E.F.Codd博士發表了一篇題爲“大型共享數據庫的數據關係模型(A Relational Model of Data for Large Shared Data Banks)”的論文,提出將數據表示爲一組表。冗餘數據用於鏈接不同表中的記錄,而不是使用指針在相關實體之間導航。如圖(1-3)顯示了George和Sue的賬戶信息在這種情況下的表示方式:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c4/c43230cfa9e94d55487516628198c8fe.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上圖(1-3)中的四個表代表了迄今爲止討論的四個實體:Customer、Product、Account和Transaction。縱觀上圖(1-3)Customer表的頂部,你可以看到三列:cust_id(包含客戶的ID號)、fname(包含客戶的名字)和lname(包含客戶的姓氏)。繼續向下看Customer表,可以看到兩個記錄行,一行包含George Blake的數據,另一行包含Sue Smith的數據。一個表能包含的最大列數因服務器而異,但這個數據通常足夠大,所以不用擔心(比如,Microsoft 的SQL Server允許每個表最多包含1024列)。一個表可能包含的行數與其說是受到數據庫服務器的限制,不如說是受到物理限制(即有多少磁盤驅動器空間可用)和可維護性(即在表中記錄數量達到怎樣的規模後仍然可以保持易用性)的問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關係數據庫中的每個表都包含一項作爲每行唯一標識的信息(稱爲主鍵),它與其他信息一起完整描述該條目。再看Customer表,cust_id列爲每個客戶保存了不同的編號;例如,George Blake可以由顧客ID 1來唯一標識,這個標識符永遠不會被分配給其他客戶,所以定位Customer表中George Blake的數據時並不需要其他的信息。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"注意:每個數據庫服務器都提供了一種機制,用於生成唯一的數字以用作主鍵值,因此你不必操心哪些數字已經被賦予爲主鍵。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然我也可能選擇使用fname和lname列的組合作爲主鍵(由兩個或更多列組成的主鍵稱爲複合主鍵),但實際上很容易出現兩個或多個姓名都相同的人都在銀行擁有帳戶的情況。因此,選擇Customer表中的cust_id列作爲主鍵是更合適的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"注意:在本例中,選擇fname/lname作爲主鍵將被稱爲自然主鍵,而選擇cust_id將被稱爲代理鍵( surrogate key)。到底選哪一種鍵取決於數據庫設計者,但在這種本例中的選擇是顯而易見的,因爲一個人的姓可能會更改(例如,當一個人使用配偶的姓時),但是主鍵一旦分配了值就不能更改。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有些表還包含用於導航到另一個表的信息,這就是前面提到的“冗餘數據”。例如,Account表包括一個名爲cust_id的列,該列包含使用該帳戶的客戶的唯一標識,以及一個名爲product_id的列,該列包含帳戶所關聯產品的唯一標識,這些列稱爲外鍵,它們的作用與賬戶信息網絡結構中各實體之間的連線相同。如果你正在查看一個特定的帳戶記錄,並且希望瞭解有關該客戶的更多信息,你可以獲取cust_id列的值,並使用它在Customer表中查找相應的行(在關係數據庫術語中,這個過程稱爲連接(join),會在第三章介紹,並在第五章和第十章進行深入探討)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多次存儲相同的數據似乎很浪費,但是某些情況下使用冗餘數據可以更清楚地體現關係模型。例如,Account表包含一列作爲開戶客戶的唯一標識符是合適的,但是如果在Account表中包含該客戶的名字和姓氏就不合適了。如果客戶要更改其姓名,你需要確保數據庫中只有一個地方保存客戶的姓名;否則,數據可能會在一個地方更改,而不會在另一個地方更改,從而導致數據庫中數據的不可靠(數據的不一致)。此數據的適當位置是Customer表,其他表中只應包括cust_id值。一個列包含多條信息也是不合適的,例如使用name列同時包含用戶的姓和名,或者使用address列包含街道、城市、州和郵政編碼信息。優化數據庫設計以確保每個獨立信息只存放在一個位置(外鍵除外)的過程稱爲規範化。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓我們回到上圖(1-3)中的四個表,你可能想知道如何使用這些表來查找George Blake在checking上的賬戶交易。首先,在Customer表中找到George Blake的唯一標識符(主鍵)。然後,在Account表中找到一行,該行的cust_id列包含George的唯一標識符,其product_id列與Product表中name列等於“Checking”的行匹配。最後,通過匹配Account表的唯一標識account_id列來定位Transaction表中對應的行。這聽起來可能很複雜,但其實在SQL語言中,用一個命令就可以完成這些任務了,稍後你將看到這一點。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"一些術語","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我在前面的章節中介紹了一些新的術語,所以也許是時候給出一些正式的定義了。下表(1-1)顯示了本書餘下部分使用術語的定義:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/004d4d17bebb14e9468c765a6908e59d.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是SQL","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根據Codd對關係模型的定義,他提出了一種稱爲DSL/Alpha的語言來處理關係表中的數據。Codd的論文發表後不久,IBM建立一個小組根據Codd的想法構建了一個原型。這個小組創建了一個簡化的DSL/Alpha版本,他們稱之爲SQUARE。對SQUARE的改進產生了一種稱爲SEQUEL的語言,它最終被縮短爲SQL。雖然SQL最初是一種用於操控關係數據庫中的數據的語言,但在本書的最後你會知道,它已經發展成了一種跨各種數據庫技術操作數據的語言。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"距今爲止,SQL已經有40多年的歷史了,在這一期間它發生了巨大的變化。在20世紀80年代中期,美國國家標準協會(American National Standards Institute,ANSI)開始爲SQL語言制定第一個標準,該標準於1986年發佈,隨後對其不斷改進,在1989年、1992年、1999年、2003年、2006年、2008年、2011年和2016年發佈了一系列新的SQL標準。除了對核心語言的改進之外,SQL語言還添加了新的特性,以結合面向對象等其他功能。後來的標準側重於相關技術的集成,如可擴展標記語言( extensible markup language,XML)和JavaScript對象表示法(JavaScript object notation,JSON)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SQL與關係模型密切相關,因爲SQL查詢的結果是一個表(在本文中也稱爲結果集)。因此,只需存儲查詢的結果集,就可以在關係數據庫中創建一個新的固定表。同樣地,一個查詢可以使用固定表和來自其他查詢的結果集作爲輸入(我們將在第九章對此進行詳細探討)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後要注意一點:SQL不是任何短語的縮寫(儘管許多人堅持認爲它代表“結構化查詢語言Structured Query Language”)。當提到該語言時,可以使用單獨的字母(即S.Q.L)或使用sequel一詞。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"SQL語句的類別","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SQL語言分爲幾個不同的部分:我們在本書中探討的部分包括SQL案例(schema)語句,用於定義存儲在數據庫中的數據結構;SQL數據(data)語句,用於操作SQL案例語句所定義的數據結構;以及SQL事務(transaction)語句,用於開始、結束和回滾事務(將在第十二章介紹)。比如,要在數據庫中創建一個新表,可以使用SQL 案例語句create table,而要在新表中插入數據則需要SQL數據語句insert。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了讓你瞭解這些句子是怎樣的,下面給出了一個SQL案例語句,它創建了一個名爲corporation的表:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CREATE TABLE corporation","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(corp_id SMALLINT,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name VARCHAR(30),","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CONSTRAINT pk_corporation PRIMARY KEY (corp_id)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":");","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該語句創建一個包含兩列的表,列爲corp_id和name,其中corp_id列被設置爲表的主鍵。在第二章中,我們將探討此語句更多的細節,比如MySQL提供的各種不同的數據類型。下面是一條SQL數據語句,它將向corporation表插入一行關於Acme Paper Corporation的數據:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INSERT INTO corporation (corp_id, name)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"VALUES (27, 'Acme Paper Corporation');","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此語句向corporation表中添加一行數據,其中corp_id列的值爲27,name列的值爲Acme Paper Corporation。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,這裏給出一條簡單的select語句來檢索剛剛創建的數據:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"mysql< SELECT name","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-> FROM corporation","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-> WHERE corp_id = 27;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+--------------------------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"| name |","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+---------------------------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"| Acme Paper Corporation |","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+---------------------------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過SQL案例語句創建的所有數據庫元素都存儲在一組稱爲數據字典的特殊表中。這種“關於數據庫的數據”統稱爲元數據,我們將在第十五章中討論它。與用戶自己創建的表一樣,數據字典表也可以通過select語句來查詢,從而允許在運行時查看部署在數據庫中的當前數據結構。例如,如果你被要求寫一份報告來顯示上個月創建的新帳戶,那麼你可以硬編碼account表中的各個列名,也可以查詢數據字典以確定當前列集,並在每次運行的時候動態生成報表。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本書的大部分內容涉及SQL語言的數據部分,其中包括select、update、insert和delete命令。SQL案例語句在第二章中演示,它將引導你完成一些簡單表的設計和創建。一般來說,除了語法之外,SQL案例語句不需要太多的研究,而SQL數據語句雖然數量很少,卻是非常值得研究的。因此,儘管我試圖介紹很多SQL案例語句,但本書的大部分章節都會側重於SQL數據語句。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"SQL:非過程化語句","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你以前使用過編程語言,那麼你會習慣於定義變量和數據結構、使用條件邏輯(即if-then-else)和循環結構(即do-while-end),並將代碼分解爲可重用的小片段(即對象、函數、過程)。你的代碼會被交付給編譯器,給出的可執行文件能夠精確地(但其實不是總是精確的)符合你編程的預期。無論你使用的是Java、Python、Scala還是其他一些過程化語言,你都可以完全控制程序的功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"注意:過程化語言定義了期望的結果和生成結果的機制或過程。非過程化語言也定義了期望的結果,但是生成結果的過程留給了外部代理來定義。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然而使用SQL需要放棄一些對過程的控制,因爲SQL語句定義了必要的輸入和輸出,而語句的執行方式交付給數據庫引擎的一個組件——優化器(optimizer)。優化器的任務是查看SQL語句,並考慮表的配置方式和有無索引可用等,以確定最有效的執行路徑(當然,並不總是最有效的)。大多數數據庫引擎都允許通過指定優化器選項來影響優化器的決策,例如建議使用特定的索引等。然而,大多數SQL用戶永遠都不需要考慮得這麼複雜,而是會將它留給數據庫管理員或性能調優專家來處理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此只使用SQL是無法編寫完整的應用程序的,除非是一些操作某些數據的簡單腳本,否則一般都需要將SQL與你喜歡用的編程語言相集成。一些數據庫供應商已經做到了這一點,例如Oracle的PL/SQL語言、MySQL的存儲過程語言,還有Microsoft的Transact-SQL語言。使用這些語言的時候,SQL數據語句是該語言語法的一部分,能夠將數據庫查詢與過程化命令無縫集成。但是,如果你使用的是非特定於數據庫的語言(如Java或Python),則需要使用一些由數據庫供應商提供的工具包/API來執行SQL語句。有些工具包是由數據庫廠商提供的,而另一些則是由第三方廠商或開放源代碼提供者所創建。下表(1-2)顯示了將SQL集成到特定語言中的一些可用選項:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/68/6809d80bdd7384ef8112707c7647e7a2.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"倘若你只需要以交互方式執行SQL命令,那麼每個數據庫開發商至少都會提供一個簡單的命令行工具,用於將SQL命令提交到數據庫引擎並檢查結果。大多數開發商也提供了圖形化工具,包括一個顯示SQL命令的窗口和另一個顯示SQL命令結果的窗口。此外,還有第三方工具,如SQuirrel,它通過JDBC連接到許多不同的數據庫服務器。由於本書中的示例是針對MySQL數據庫執行的,因此我使用MySQL安裝文件中包含的mysql命令行工具來運行示例並格式化結果。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"SQL示例","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本章前面,我承諾過會展示一個返回George Blake的checking賬戶上所有交易的SQL語句,廢話少說,語句和查詢結果如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SELECT t.txn_id, t.txn_type_cd, t.txn_date, t.amount","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FROM individual i","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INNER JOIN account a ON i.cust_id = a.cust_id","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INNER JOIN product p ON p.product_cd = a.product_cd","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INNER JOIN transaction t ON t.account_id = a.account_id","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WHERE i.fname = 'George' AND i.lname = 'Blake'AND p.name = 'checking account';","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+--------+-------------+---------------------+--------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"| txn_id | txn_type_cd | txn_date | amount |","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+--------+-------------+---------------------+--------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"| 11 | DBT | 2008-01-05 00:00:00 | 100.00 |","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"+--------+-------------+---------------------+--------+","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1 row in set (0.00 sec)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏就簡單地分析一下該語句:該查詢在individual表中查找姓名爲George Blake的行,以及查詢在product表中賬戶名爲checking account的行,並通過account表將它們關聯起來,然後返回transaction表中所有提交到該賬戶上面的交易信息內容,分爲四列顯示。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你碰巧知道George Blake的客戶ID爲8,並且checking賬戶的指定代碼爲“CHK”,那麼你只需在account表中根據客戶ID查找George Blake的checking賬戶,並使用賬戶ID查找相應的交易:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SELECT t.txn_id, t.txn_type_cd, t.txn_date, t.amount","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FROM account a","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INNER JOIN transaction t ON t.account_id = a.account_id","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WHERE a.cust_id = 8 AND a.product_cd = 'CHK';","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在接下來的章節中,我將介紹這些查詢中的所有概念(並且還會涉及更多概念),但我至少在這裏想展示一下它們的大致結構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面的查詢包含三個不同的子句:select、from和where。幾乎你遇到的每個查詢都將至少包含這三個子句,當然還有幾個子句可以用於更加特定的查詢。三個字句的作用如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SELECT /* one or more things ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"/ ...","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"FROM /","attrs":{}},{"type":"text","text":" one or more places ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"/ ...","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"WHERE /","attrs":{}},{"type":"text","text":" one or more conditions apply */ ...","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"注意:大多數SQL實現都將/","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"size","attrs":{"size":10}}],"text":"和","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"/標記之間的所有文本視爲註釋。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"構造查詢時,你首先要做的通常是確定需要哪些表,然後將它們添加到from子句中。接下來,你需要向where子句添加查詢條件,以便從這些表中篩選出你不感興趣的數據。最後,你要確定需要檢索不同表中的哪些列,並將它們添加到select子句中。下面是一個簡單的示例,該例子展示瞭如何找到所有姓爲“Smith”的客戶:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SELECT cust_id, fname","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"FROM individual","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WHERE lname = 'Smith';","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此查詢在individual表中搜索lname列與字符串“Smith”匹配的所有行,並從這些行返回cust_id和fname列。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了查詢數據庫外,可能還需要插入和更新數據庫中的數據。下面是一個簡單的示例,說明如何在product表中插入新行:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"INSERT INTO product (product_cd, name)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"VALUES ('CD', 'Certificate of Depysit')","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"啊咧,看來你把“Deposit”拼錯了,不過沒關係,你可以使用update語句:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UPDATE product","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SET name = 'Certificate of Deposit'","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WHERE product_cd = 'CD';","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意,update語句和select語句一樣包含where子句,這是因爲update語句必須識別要修改的行。在本例中,指定只修改product_cd列與字符串“CD”匹配的行。由於product_cd列是product表的主鍵,因此應該期望update語句只修改一行(如果表中不存在該值,則爲零行)。每當你執行SQL data語句時,你都會收到來自數據庫引擎的反饋,顯示其中有多少行受本次執行語句的影響。如果你使用的是交互式工具,如前面提到的mysql命令行工具,那麼你將收到以下關於操作影響行數的反饋:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•由select語句返回","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•由insert語句創建","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•由update語句修改","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•由delete語句刪除","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你將過程化語言與前面提到的某個工具箱一起使用,那麼該工具箱將包含一個調用,以便在執行SQL數據語句後獲得此信息。一般來說,最好是檢查此信息以確保語句沒有執行意外操作(比如忘記在delete語句中編寫where子句,導致刪除表中的所有行)。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是MySQL","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關係數據庫已經商業化三十多年了,幾種最成熟和流行的商業產品包括:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•Oracle公司的Oracle Database","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•Microsoft的SQL Server","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•IBM提供的DB2 Universal Database","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有這些數據庫服務器都執行大致相同的操作,儘管其中的一些更適合運行大容量和高吞吐量的數據庫,而另一些更擅長處理對象、大文件或XML文檔等。此外,所有這些服務器都遵從最新的ANSI SQL標準。這是一件好事,我將重點向你展示如何編寫標準SQL語句,以便不進行或者只進行少量修改就可以在這些平臺上運行。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着商業數據庫服務器的出現,在過去的二十年中,開源社區正在爲創建一個可行的替代案例而努力。最常用的兩個開源數據庫服務器是PostgreSQL和MySQL。MySQL服務器是免費的,並且非常便於下載和安裝。基於這些原因,本書的所有示例都將在MySQL(8.0版)運行,並使用mysql命令行工具格式化查詢結果。即便你使用的是另外一種數據庫並且也沒打算使用MySQL,我還是建議你安裝最新的MySQL服務器,加載示例模式和數據,並嘗試使用本書中的數據和示例。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"但是,還請牢牢記住以下告誡:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"本書並不是一本關於MySQL的SQL實現教程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相反,本書的目的是教你如何編寫SQL語句,這些語句將在MySQL上運行而不做任何修改,並且在做很少或根本不做任何修改的情況下移植到Oracle Database、DB2和SQL Server上。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"不只是SQL","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本書出版第二版和第三版的十年間,數據庫領域內發生了很多事情。儘管關係型數據庫現在還在大量使用,並且也將持續一段時間,但是新的數據庫技術已經出現並滿足了亞馬遜和谷歌等公司的需求。這些技術包括Hadoop、Spark、NoSQL和NewSQL,它們是分佈式、可擴展的系統,通常部署在商品服務器集羣上。雖然詳細探討這些技術並不在本書的範圍之內,但是它們卻和關係數據庫有一些共同點:SQL。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於組織經常使用多種技術存儲數據,因此需要從特定的數據庫服務器中“拔出”SQL,並提供一種可以跨多個數據庫的服務。例如,一份報表可能需要將存儲在Oracle、Hadoop、JSON文件、CSV文件和Unix日誌文件中的數據合併在一起。新一代的工具已經被用來應對這類挑戰,其中最有前途的是Apache Drill,它是一個開源的查詢引擎,允許用戶編寫查詢來訪問存儲在大多數數據庫或文件系統中的數據。我們將在第十八章中探討Apache Drill。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"內容提要","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來四章的主要目標是介紹SQL數據語句,並且會特別強調select語句的三個主要子句。此外,你將看到許多使用Sakila模式的示例(將在下一章中介紹),本書的所有示例都圍繞它展開。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我希望通過熟悉單個數據庫,讓你可以瞭解示例的關鍵之處,而不必每次都停下來了解所使用的表。如果你覺得使用同一組表太無聊了,那也可以隨意使用其他表來擴充示例數據庫,或者創建自己的數據庫來進行實驗。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在幫你牢固地掌握基礎了知識之後,剩下的章節將深入探討其他概念,其中大多數概念是相互獨立的。因此,如果你在學習這些章節的過程中感到困惑,也可以繼續學習後面的內容,稍後再重溫這一章的內容。當你讀完這本書並學習了所有的示例之後,你很快就能成爲一名經驗豐富的SQL實踐者了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於有興趣瞭解更多關係數據庫、計算機數據庫系統的歷史或SQL語言的讀者,下面給出了一些值得參考的資源","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•Database in Depth: Relational Theory for Practitioners by C. J. Date (O’Reilly)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•An Introduction to Database Systems, Eighth Edition, by C. J. Date (Addison-Wesley)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•The Database Relational Model: A Retrospective Review and Analysis, by C. J. Date (Addison-Wesley)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"•Wikipedia subarticle on definition of “Database Management System”","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章