天天看點

《SQL學習指南(第2版)(修訂版)》——1.2 什麼是SQL

本節書摘來自異步社群出版社《sql學習指南(第2版)(修訂版)》一書中的第1章,第1.2節,作者: 【美】alan beaulieu,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

sql學習指南(第2版)(修訂版)

根據codd對關系模型的定義,他提出一種名為dsl/alpha的語言,用于操控關系表的資料。在codd的論文發表後不久,ibm建立了一個研究小組來根據他的想法建構原型。該小組建立了一個dsl/alpha的簡化版本,即square,然後通過對square的改進,将之發展為sequel語言,并最終命名為sql。

今天sql已經發展到了中年期(唉,就像作者一樣),在這期間它經曆了大量修改。在20世紀80年代中期,美國國家标準組織(ansi)開始制定sql語言的第一個标準,并于1986年釋出。其後不斷對其改進,并在1989年、1992年、1999年、2003年和2006年釋出了一系列sql标準的新版本。通過對語言核心的改良,新的特性被陸續加入到sql語言中,以吸收面向對象等其他功能。最後一個标準版本,sql 2006則聚焦于sql和xml的內建,并定義了xquery語言以用于在xml文檔中查詢資料。

sql與關系模型的關系密切,因為sql查詢的結果也可以視為一張表(在程式上下文中稱之為結果集)。是以,可以在關系資料庫中簡單地建立一個固定表,用于存放查詢的結果集。同樣地,sql查詢也可以使用固定表或其他查詢的結果集作為其輸入(在第9章中将會講述其細節)。

最後需要注意的一點是:sql并不是任何短語的縮寫(盡管許多人堅持認為它代表結構化查詢語言(structured query language))。當提到此語言時,可以使用獨立的字母(s.q.l)或使用單詞sequel。

在本書中,将分别讨論sql語言的幾個獨立子產品,即sql 方案(schema)語句,用于定義存儲于資料庫中的資料結構;sql資料語句,用于操作sql方案語句所定義的資料結構;以及sql事務語句,用于開始、結束或復原事務(将在第12章中介紹)。例如,在資料庫中建立新表時,需要使用sql方案語句create table,而在新表中産生資料則需要sql資料語句insert。

下面給出這些語句的具體例子,用于建立corporation表的sql方案語句如下:

該語句建立的表包括兩列:corp_id和name。其中,corp_id列被設定為表的主鍵。在第2章中,将會介紹該語句的細節,比如mysql中所提供的各種資料類型。下面給出的sql資料語句将向corporation表中插入一行關于acme paper corporation的資料:

該語句向corporation表中添加了一行資料,其中corp_id列的值為27,而name列的值是acme paper corporation。

最後,給出一條簡單的select語句,以擷取剛才建立的資料:

通過sql方案語句所建立的所有資料庫元素都被存儲在一個特殊的表集合,即資料字典中。這些“關于資料庫的資料”一般被稱為“中繼資料”,本書第15章将對此進行詳細介紹。與使用者所建立的表一樣,資料字典表也可以通過select語句查詢,進而允許在運作時刻檢視資料庫中的目前資料結構。例如,使用者需要編寫顯示上月新增賬戶的報表,那麼既可以在報表中對account表的各個列名進行寫死,也可以通過查詢資料字典以擷取目前的列集合并在每次運作時動态地建立報表。

本書中的大部分篇幅将聚焦于sql語言中的資料相關部分,包括select、update、insert和delete指令。sql方案語句将在第2章中說明,并且該章所建立的示例資料庫将在全書中使用。一般來說,不需要對sql方案語句的文法進行太多論述,而對于sql資料語句,盡管隻有寥寥幾條,但其中包含了大量值得仔細研究的内容。是以,盡管我盡量介紹更多的sql方案語句,但本書的大多數章節還是把重點放在sql資料語句上。

如果讀者有過程式設計語言的使用經驗,可能習慣于定義變量或資料結構、使用條件邏輯(即if-then-else)和循環結構(即do-while-end),并将程式代碼分成可複用的小片段(如對象、函數、過程等)。這些代碼經過編譯後執行,其執行結果精确地(也并不是總是精确)符合程式設計的預期。無論是使用java、c#、c、visual basic還是其他過程化語言,都可以完全控制程式的行為。

提示

過程化語言對所期望的結果和産生這些結果的執行機制或過程都進行了定義。非過程化語言同樣定義了期望結果,但将産生結果的過程留給外部代理來定義。

使用sql意味着必須放棄對過程的控制,因為sql語句隻定義必要的輸入和輸出,而執行語句的方式則交由資料庫引擎的一個元件,即優化器(optimizer)處理。優化器的工作包括檢視sql語句并考慮該表的配置資訊以及有無索引等,以确定最具效率的執行路徑(當然,并不總是最有效率)。大多數資料庫引擎允許通過指定優化器選項來影響優化器的決策,比如建議使用特定的索引等。而大多數sql的使用者并不需要考慮這個複雜的層面,而是将之交給資料庫管理者或性能調優專家來處理。

是以單獨使用sql并不能開發完整的應用,除了編寫簡單的腳本來處理某些資料,一般需要将sql與程式設計語言相內建。一些資料庫廠商已經為使用者考慮了這些,如oracle的pl/sql語言,mysql的存儲過程語言,以及microsoft的transact-sql語言。在這些語言中,sql資料語言是其文法的一部分,以準确無誤地将資料庫查詢與過程化指令內建到一起。如果使用非資料庫指定的語言,如java等,則需要使用工具集/api以在代碼中執行sql語句。有些工具集由資料庫廠商提供,其他的則由第三方廠商或開源代碼提供者所建立。表1-2顯示了将sql內建到特定語言的可用選項。

《SQL學習指南(第2版)(修訂版)》——1.2 什麼是SQL

如果使用者僅僅需要執行互動式的指令,那麼每種資料庫開發商都提供了至少一個簡單的指令行工具,用于向資料庫引擎送出sql指令。大多數開發商都提供了圖形化的工具,其中包含顯示sql指令的視窗以及另一個顯示sql指令執行結果的視窗。因為本書中的例子都将在mysql資料庫中運作,是以本書使用mysql指令行工具。該工具屬于mysql安裝檔案的一部分,并用于運作示例和格式化的結果。

1.2.3 sql示例

在本章前面,我說過要示範傳回george blake的checking賬戶上所有交易的sql語句,下面就兌現這個承諾,語句和查詢結果如下:

此處僅對此語句進行簡單的分析:該查詢查找滿足下面兩個條件的行,即在individual表中姓名為george blake的行,以及在product表中的賬戶名為checking account的行,并通過account表将它們關聯起來,然後傳回transaction表中所有送出到該賬戶上的交易資訊内容,并分4列顯示。如果剛好知道george blake的客戶id是8并且checking賬戶的指定代碼為“chk”,就可以簡單地根據客戶id找到george blake在account表中的checking賬戶,并使用賬戶id來查找相關的交易:

在下面的各章節裡,将會覆寫到這些查詢的所有概念(并且會涉及得很多),但在這裡至少需要展示一下它們的大緻結構。

前面的查詢包含了3個不同的字句,包括select、from和where。幾乎所有的查詢都至少會包含這3個子句,當然還有其他幾個子句可用于更特定的查詢目标。下面展示了這3個子句所起的角色:

大多數的sql實作都将/和/标記之間的文本視為注釋。

當使用者構造查詢時,首先需要确定查找的是哪一個或哪些表,并将它們加入from子句中,然後在where子句中增加查詢條件以過濾掉并不感興趣的資料。最後,需要确定從各個表中所應提取的列,并将之增加到select子句中。下面給出一個簡單的例子,以展示如何找到所有姓為“smith”的客戶:

該查詢搜尋individual表,以找到所有lname列比對字元串'smith'的行,并傳回這些行中的cust_id和fname列。

除了查詢資料庫,還需要在資料庫中建立和修改資料,下面舉出一個簡單的例子,以說明如何在product表中插入新行:

糟糕,這裡将“deposit”拼錯了,不過沒有關系,可以使用update語句來修複這個錯誤:

注意,與select語句一樣,update語句也包含了where子句,這是因為update語句也要識别所需修改的行。在本例中,隻需要将要修改的行指定為product_cd列與字元串'cd'相比對的那些行即可。由于product_cd列是product表的主鍵,是以可以預計update語句會精确地修改某一行(或零行,如果表中該值不存在)。在任何時刻執行sql資料語句,都會收到一個來自資料庫引擎的回報,以顯示該語句所影響的行數。如果使用互動式工具,比如上文提到的mysql指令行工具,那麼可以接收到下面幾種操作所影響行數的回報:

select語句的傳回行數;

insert 語句建立的行數;

update語句修改的行數;

delete語句所删除的行數。

可以使用過程化語言,并結合上文提到的工具集來調用sql語句。工具集通常包含了能夠擷取sql資料語句執行資訊的調用。一般來說,好的做法應當是檢查這個資訊以确信語句執行并沒有超出預料(比如忘記為delete語句增加where子句,進而删除了表中的所有行)。

本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。