SQL達人的現場工作筆記 - Ch12 - SQL程式設計的模式

前言

除了寫出可以運作的 SQL 外,對於 SQL 的維護也是相當重要,所以本章節將討論在撰寫 SQL 上的可讀性。

資料表設計

名稱與意義

在 SQL 中對應的欄位、資料表、索引應該都要賦予有意義的命名

SQL 中可以使用的三種文字

  1. 英文字母
  2. 數字
  3. 底線( _ )

雖然有些 SQL 系統也承認像是 $、#、* 之類的符號,但作者建議大家不要去使用,因為有可能會在需要將資料庫移植到別的系統上的時候出問題(例如:MySQL 移植到 Postgres)

另外作者也告訴大家請不要使用保留字(例如:Primary)當作命名,這會增加混亂

屬性與欄位

比起將資料表涉及為 EAV(實體屬性值) 的方式,更建議將各種資料用途拆開,讓欄位去說明資料的本質

撰寫程式的方針

註解

在 clean code 裡面有討論到,我們應該要盡量讓命名取代註解
但作者認為 SQL 絕對應該要給註解,他給出的理由有二

  1. SQL 為宣告型語言,所以很難寫出像其他程式語言那種「能夠自己解釋自己的程式碼」
  2. SQL 幾乎無法 step by step 去檢驗錯誤

註解的寫法有下列兩種

  1. 1
    2
    3
    4
    -- 單行註解
    -- 從 SomeTable 取出 col_1
    SELECT col_1
    FROM SomeTable
  2. 1
    2
    3
    4
    5
    /*
    多行註解
    從 SomeTable 取出 col_1 */
    SELECT col_1
    FROM SomeTable

SQL 的程式碼可以像下面這樣參雜註解增加可讀性

1
2
3
4
5
6
7
8
9
10
11
SELECT col_1
FROM SomeTable
WHERE col_1 = 'a'
AND col_2 = 'b'
-- 以下的條件將指定 col_3 為 c 或 d 其中一個
AND col_3 IN ('c', 'd');

-----------------------------------------

SELECT col_1 --從 SomeTable 取出 col_1
FROM SomeTable

縮排

簡單的說就是 SQL 的程式碼必須要縮排才容易閱讀,不過書中並沒有對於縮排規範有詳細的描述。

但我去找了一下關於 SQL 撰寫的 Style 規範,發現了 SQL Style Guide 這個網站,有興趣可以去看一下

空白字元

簡單的說就是文字排版要適當的插入空白才比較好閱讀,在 SQL Style Guide 也有提到關於加入空白的時機的規範

大寫與小寫

請將保留字大寫,欄位名稱小寫,範例如下

1
2
3
4
SELECT first_name AS fn
FROM staff AS s1
JOIN students AS s2
ON s2.mentor_id = s1.staff_num;

逗號

作者介紹了一種「前逗號」的排版方式,如範例

1
2
3
4
5
SELECT col_1
,col_2
,col_3
,col_4
FROM tab_A

這種排版有兩個優點

  1. 假如直接刪除範例 code 的第四行 col_4 的部分也不會出錯,反之如果採用「後逗號」的方式則會報錯
  2. 編輯器可以做快速編輯(筆者:這點我想對於現在的編輯器來說比較沒有影響,畢竟功能都相當強大了)

不過作者自己也表示,這種做法其實有損於「易讀性」,只是這樣的做法有些優點,所以拿出來討論一下,當自己評估優點對開發來說相當重要的時候,或許也可以採用

另外, SQL Style Guide 是提倡「後逗號」的做法的

不使用萬用字元

使用萬用字元 * 除了會拿出多餘的資料,對於效能造成影響外,也會對可讀性造成影響

在使用 * 的狀況下,我們並沒有辦法一眼看出我們拿出來的實際的東西是什麼,往往都還要經由去比對原本資料表的欄位才知道有什麼欄位可以用

1
2
3
4
5
-- X
SELECT * FROM SomeTable

-- O
SELECT col_1, col_2 FROM SomeTable

不在 ORDER BY 使用欄位編號

在使用 ORDER BY 的時候可以用欄位編號代替實際的欄位名稱,但這樣非常難閱讀,此功能也被 SQL-92 列為將來要刪除的功能

1
2
3
4
5
-- X
SELECT col_1, col_2 FROM SomeTable ORDER BY 1, 2;

-- O
SELECT col_1, col_2 FROM SomeTable ORDER BY col_1, col_2;

學習標準語

在眾多程式語言中, SQL 算是「方言」比較多的類型(在 MySQL 、 Postgres 中都有自己的特化語法),如果使用這些「方言」去撰寫的話,在移植資料庫系統的時候就會有很大的問題,所以建議盡量使用標準化的語法去撰寫 SQL

左派與右派(?)

驅逐關聯子查詢

關聯子查詢的語法困難,又不容易除錯,也無法獨立執行

從 FROM 陳述句開始撰寫

一般來說我們在撰寫 SQL 的習慣都是從 SELECT 開始撰寫,但是 SQL 底層的執行順序卻是

1
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT

作者認為,當 SQL 語法相當複雜的時候可能會帶有很巨大的 SELECT 區塊,這時候如果從 FROM 開始寫的話,會比較容易知道下條件的邏輯,而且也能夠遵循 SQL 執行的脈絡

不過筆者認為,這個跟「前逗號」一樣都蠻違反我們所習慣的規則的,況且當 SQL 語句相當複雜的時候,會造成理解上的障礙的也不見得會是 SELECT 區塊