理解SQL(1,2,3)

1、 SQL 是一種聲明式語言

首先要把這個概念記在腦中:“聲明”。 SQL 語言是爲計算機聲明瞭一個你想從原始數據中獲得什麼樣的結果的一個範例,而不是告訴計算機如何能夠得到結果。這是不是很棒?
(譯者注:簡單地說,SQL 語言聲明的是結果集的屬性,計算機會根據 SQL 所聲明的內容來從數據庫中挑選出符合聲明的數據,而不是像傳統編程思維去指示計算機如何操作。)

SELECT first_name, last_name FROM employees WHERE salary > 100000

上面的例子很容易理解,我們不關心僱員記錄從哪來,只關心哪些記錄是高薪者的數據(salary > 100000)

我們從哪兒學習到這些?

如果 SQL 語言這麼簡單,那麼是什麼讓人們“聞 SQL 色變”?主要的原因是:我們潛意識中的是按照命令式編程的思維方式思考問題的。就好像這樣:“電腦,先執行這一步,再執行那一步,但是在那之前先檢查一下是否滿足條件 A 和條件 B ”。例如,用變量傳參、使用循環語句、迭代、調用函數等等,都是這種命令式編程的思維慣式。

2、SQL的語法並不按照語法的書寫順序執行

就是;SQL語句的執行順序跟其語句的語法順序並不一致。
SQL語句的語法順序:
• SELECT[DISTINCT]
• FROM
• WHERE
• GROUP BY
• HAVING
• UNION
• ORDER BY
上面並沒有把所有的SQL語法結構都列出來,但是已經足以說明SQL語句的語法順序和其執行順序完全不一樣,上述語句執行順序:
• FROM
• WHERE
• GROUP BY
• HAVING
• SELECT[DISTINCT]
• UNION
• ORDER BY
執行順序,有三個值得我們注意的地方:
1、FROM纔是SQL語句執行的第一步。數據庫在執行SQL語句的第一步是將數據從硬盤加載到數據緩衝區中,以便對這些數據進行操作。(譯者注:原文爲“The first thing that happens is loading data from the disk into memory, in order to operate on such data.”,但是並非如此,以 Oracle 等常用數據庫爲例,數據是從硬盤中抽取到數據緩衝區中進行操作。)
2、SELECT是在大部分語句執行了之後才執行的,嚴格的說是在FROM和GROUP BY之後執行的。這一點非常重要,這就是你不能在WHERE中使用在SELECT中設定別名的字段作爲判斷條件的原因。

SELECT A.x + A.y AS z
FROM A
WHERE z = 10 -- z 在此處不可用,因爲SELECT是最後執行的語句!

如果你想重用別名z,你有兩個選擇,要麼就重新寫一遍z所代表的表達式:

SELECT A.x + A.y AS z
FROM A
WHERE (A.x + A.y) = 10

。。。或者求助於衍生表、通用數據表達式或者視圖,以避免別名重用。請看下文中的例子。
3、無論在語法上還是執行順序上,UNION總是排在ORDER BY之前。很多人認爲每個UNION段都能使用ORDER BY排序,但根據SQL語言標準以及各個數據庫SQL執行差異,並不是的。某些數據庫允許SQL語法對子查詢(subqueries)或派生表(derived table)進行排序,但這並不能說明這個排序在UNION操作之後仍保持排序後的順序。
注意:並非所有的數據庫對 SQL 語句使用相同的解析方式。如 MySQL、PostgreSQL和 SQLite 中就不會按照上面第二點中所說的方式執行。

我們學到了什麼?

我們要永遠都記得:SQL語句的語法順序和其執行順序並不一致,這樣我們就能避免一般性的錯誤。如果你能記住SQL語句語法順序和執行順序的差異,你就能理解一些很常見的SQL問題。
當然,如果一種語言被設計成語法順序直接反映其語句的執行順序,那麼這種語言對程序員是十分友好的,這種編程語言層面的設計理念已經被微軟應用到了LINQ語言中

3、SQL語言的核心是對錶的引用(table references)

其實真正的核心在於對錶的引用
根據SQL標準,FROM語句被定義爲:

<from clause> ::= FROM <table reference> [ { <comma> <table reference> }... ]

FROM語句的“輸出”是一張聯合表,來自於所有引用的表在某一維度上的聯合。我們慢慢來分析:

FROM a, b

上面這句FROM語句的輸出是一張聯合表,聯合了表a和表b。如果表a有3個字段,表b有5個字段,那麼這個“輸出表”就有8(3+5)個字段。
這個聯合表裏的數據是:a*b,即a和b的笛卡兒積。也就是表a中的每一條數據都要和表b中的每一條數據配對。如果表a有3條數據,表b有5條數據,那麼,聯合表就會有15(3*5)條數據。
FROM輸出的結果被WHERE語句篩選後要經過GROUP BY語句處理,從而形成新的處理結果。後面還會再討論這方面。
如果我們從集合論(關係代數)的角度來看,一張數據庫的表就是一組數據元的關係,而每個SQL語句會改變一種或數種關係,從而產生出新的數據元的關係(即產生新的表)。

我們學到了什麼?

思考問題的時候從表的角度來思考問題,這樣很容易理解數據如何在SQL的“流水線”上進行了怎樣的變動。

Oct 31st, 2016

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章