如果我們從集合論(關系代數)的角度來看,一張數據庫的表就是一組數據元的關系,而每個?SQL?語句會改變一種或數種關系,從而產生出新的數據元的關系(即產生新的表)。
我們學到了什么?
思考問題的時候從表的角度來思考問題提,這樣很容易理解數據如何在?SQL?語句的“流水線”上進行了什么樣的變動。
4、?靈活引用表能使?SQL?語句變得更強大
靈活引用表能使?SQL?語句變得更強大。一個簡單的例子就是?JOIN?的使用。嚴格的說?JOIN?語句并非是?SELECT?中的一部分,而是一種特殊的表引用語句。?SQL?語言標準中表的連接定義如下:
<table?reference?>?::=?
<table?name?>
|?<derived?table?>
|?<joined?table?>?
就拿之前的例子來說:
FROM?a,?b?
a?可能輸如這樣的連接:a1?JOIN?a2?ON?a1.id?=?a2.id?
將它放到之前的例子中就變成了:FROM?a1?JOIN?a2?ON?a1.id?=?a2.id,?b?
盡管將一個連接表用逗號跟另一張表聯合在一起并不是常用作法,但是你的確可以這么做。結果就是,最終輸出的表就有了?a1+a2+b?個字段了。
(譯者注:原文這里用詞為?degree??,譯為維度。如果把一張表視圖化,我們可以想象每一張表都是由橫縱兩個維度組成的,橫向維度即我們所說的字段或者列,英文為columns;縱向維度即代?表了每條數據,英文為?record?,根據上下文,作者這里所指的應該是字段數。)
在?SQL?語句中派生表的應用甚至比表連接更加強大,下面我們就要講到表連接。
我們學到了什么?
思考問題時,要從表引用的角度出發,這樣就很容易理解數據是怎樣被?SQL?語句處理的,并且能夠幫助你理解那些復雜的表引用是做什么的。
更重要的是,要理解?JOIN?是構建連接表的關鍵詞,并不是?SELECT?語句的一部分。有一些數據庫允許在?INSERT?、?UPDATE?、?DELETE?中使用?JOIN?。
5、?SQL?語句中推薦使用表連接
我們先看看剛剛這句話:
FROM?a,?b?
高級?SQL?程序員也許學會給你忠告:盡量不要使用逗號來代替?JOIN?進行表的連接,這樣會提高你的?SQL?語句的可讀性,并且可以避免一些錯誤。
利用逗號來簡化?SQL?語句有時候會造成思維上的混亂,想一下下面的語句:
FROM?a,?b,?c,?d,?e,?f,?g,?h?
WHERE?a.a1?=?b.bx?
AND?a.a2?=?c.c1?
AND?d.d1?=?b.bc?
...?
我們不難看出使用?JOIN?語句的好處在于:
安全。?JOIN?和要連接的表離得非常近,這樣就能避免錯誤。更多連接的方式,JOIN?語句能去區分出來外連接和內連接等。
我們學到了什么?
記著要盡量使用?JOIN?進行表的連接,永遠不要在?FROM?后面使用逗號連接表。
6、?SQL?語句中不同的連接操作
SQL?語句中,表連接的方式從根本上分為五種:
EQUI?JOIN
SEMI?JOIN
ANTI?JOIN
CROSS?JOIN
DIVISION
EQUI?JOIN
這是一種最普通的?JOIN?操作,它包含兩種連接方式:
INNER?JOIN(或者是?JOIN?)
OUTER?JOIN(包括:?LEFT?、?RIGHT、?FULL?OUTER?JOIN)
SEMI?JOIN
這種連接關系在?SQL?中有兩種表現方式:使用?IN,或者使用?EXISTS。“?SEMI??”在拉丁文中是“半”的意思。這種連接方式是只連接目標表的一部分。這是什么意思呢?再想一下上面關于作者和書名的連接。我們想象一下這樣的情況:我們不?需要作者?/?書名這樣的組合,只是需要那些在書名表中的書的作者信息。那我們就能這么寫:
FROM?author
WHERE?author.id?IN?(SELECT?book.author_id?FROM?book)?
Using?EXISTS
FROM?author
WHERE?EXISTS?(SELECT?1?FROM?book?WHERE?book.author_id?=?author.id)?
盡管沒有嚴格的規定說明你何時應該使用?IN?,何時應該使用?EXISTS?,但是這些事情你還是應該知道的:
1,IN比?EXISTS?的可讀性更好
2,EXISTS?比IN?的表達性更好(更適合復雜的語句)
3,二者之間性能沒有差異(但對于某些數據庫來說性能差異會非常大)
因為使用?INNER?JOIN?也能得到書名表中書所對應的作者信息,所以很多初學者機會認為可以通過?DISTINCT?進行去重,然后將?SEMI?JOIN?語句寫成這樣:
FROM?author
JOIN?book?ON?author.id?=?book.author_id?
這是一種很糟糕的寫法,原因如下:
SQL?語句性能低下:因為去重操作(?DISTINCT?)需要數據庫重復從硬盤中讀取數據到內存中。(譯者注:?DISTINCT?的確是一種很耗費資源的操作,但是每種數據庫對于?DISTINCT?的操作方式可能不同)。
沈陽463美容醫院程序提醒:這么寫并非完全正確:盡管也許現在這么寫不會出現問題,但是隨著?SQL?語句變得越來越復雜,你想要去重得到正確的結果就變得十分困難。