1
0
Fork 0
mirror of https://github.com/treffynnon/sqlstyle.guide.git synced 2025-03-09 12:49:51 -05:00

Merge pull request #60 from JackKuo-tw/gh-pages

Fix zh-TW typos, misuse, conventions
This commit is contained in:
Simon Holywell 2020-03-05 15:22:50 +10:00 committed by GitHub
commit 370a1941df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,26 +2,26 @@
這份文件翻譯自以[創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款][licence-zh]發布的[http://www.sqlstyle.guide][sqlstyleguide],譯文以原文同樣的條款發布。 這份文件翻譯自以[創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款][licence-zh]發布的[http://www.sqlstyle.guide][sqlstyleguide],譯文以原文同樣的條款發布。
## Overview 綜述 ## 概要
你可以直接使用這些指導方針,或者[fork][fork]後創建自己的版本——最重要的是選擇一套方針並嚴格遵守它。歡迎通過提交[issue][issue]或[pull request][pull]來提交建議或修復bug。 你可以直接使用這些指導方針,或者 [fork][fork] 後創建自己的版本——最重要的是選擇一套方針並嚴格遵守它。歡迎透過提交 [issue][issue] 或 [pull request][pull] 來提交建議或修復 bug。
為了讓閱讀了Joe Celko的《[SQL ProgrammingStyle][celko]》的團隊能更容易采用這套規則,這套原則被設計成與該書的型式相容。本指南在某些領域嚴格一些,在另一些領域寬鬆一些。 當然本指南比Celko的書更簡潔一些因為Celko的書包含了一些趣聞和每一條原則背後的理由。 為了讓閱讀了Joe Celko 的《[SQL ProgrammingStyle][celko]》的團隊能更容易采用這套規則,這套原則被設計成與該書的型式相容。本指南在某些領域嚴格一些,在另一些領域寬鬆一些。 當然本指南比 Celko 的書更簡潔一些,因為 Celko 的書包含了一些趣聞和每一條原則背後的理由。
將此文檔的[Markdown format][dl-md]格式添加到專案程式庫中或將該頁面的鏈接發送給所有項目的參與者要比傳閱實體書容易得多。 將此文檔的 [Markdown format][dl-md] 格式添加到專案程式庫中或將該頁面的鏈接發送給所有項目的參與者要比傳閱實體書容易得多。
[Simon Holywell][simon]所著的《SQL樣式指南》以[創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款][licence-zh]發布,改編自[http://www.sqlstyle.guide][sqlstyleguide]。 [Simon Holywell][simon]所著的《SQL樣式指南》以[創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款][licence-zh]發布,改編自[http://www.sqlstyle.guide][sqlstyleguide]。
## General 一般原則 ## 一般原則
### Do 應該做的事情 ### 應該做的事情
* 使用一致的、敘述性的名稱。 * 使用一致的、敘述性的名稱。
* 靈活使用空格和縮排來增強可讀性。 * 靈活使用空格和縮排來增強可讀性。
* 儲存符合[ISO-8601][iso-8601]標準的日期格式(`YYYY-MM-DD HH:MM:SS.SSSSS`) * 儲存符合 [ISO-8601][iso-8601] 標準的日期格式(`YYYY-MM-DD HH:MM:SS.SSSSS`
* 最好使用標準SQL函式而不是特定供應商的函式以提高可移植性。 * 最好使用標準 SQL 函式而不是特定供應商的函式以提高可移植性。
* 保證代碼簡潔明了並消除多餘的SQL——比如非必要的引號或括號,或者可以推導出的多餘`WHERE`語句。 * 保證程式簡潔明了並消除多餘的 SQL比如非必要的引號或括號,或者可以推導出的多餘 `WHERE` 語句
* 必要時在SQL代碼中加入註解。優先使用C語言式的以`/*`開始以`*/`結束的區塊註解,或使用以`--`開始的單行註解。 * 必要時在 SQL 程式碼中加入註解。優先使用 C 語言式的以 `/*` 開始以 `*/` 結束的區塊註解,或使用以 `--` 開始的單行註解。
```sql ```sql
SELECT file_hash -- stored ssdeep hash SELECT file_hash -- stored ssdeep hash
@ -36,20 +36,20 @@ UPDATE file_system
WHERE file_name = '.vimrc'; WHERE file_name = '.vimrc';
``` ```
### Avoid 應避免的事情 ### 應避免的事情
* 駝峰命名法——它不適合快速掃描。 * 駝峰命名法——它不適合快速掃描。
* 描述性的前綴或匈牙利命名法比如`sp_`或`tbl` * 描述性的前綴或匈牙利命名法比如 `sp_``tbl`
* 複數形式——盡量使用更自然的集合術語。比如用“staff”替代“employees”或用“people”替代“individuals”。 * 複數形式——盡量使用更自然的集合術語。比如用“staff”替代“employees”或用“people”替代“individuals”。
* 需要引用號的標識符——如果你必須使用這樣的標識符最好堅持用SQL92的雙引號來提高可移植性。 * 需要引用號的標識符——如果你必須使用這樣的標識符最好堅持用SQL92的雙引號來提高可移植性。
* 物件導向程式設計的原則不該應用到結構化查詢語言或資料庫結構上。 * 物件導向程式設計的原則不該應用到結構化查詢語言或資料庫結構上。
## Naming conventions 命名慣例 ## 命名慣例
### General 一般原則 ### 一般原則
* 保證名字獨一無二且不是[保留字][reserved-keywords]。 * 保證名字獨一無二且不是[保留字][reserved-keywords]。
* 保證名字長度不超過30個字節。 * 保證名字長度不超過 30 個字節。
* 名字要以字母開頭,不能以下底線結尾。 * 名字要以字母開頭,不能以下底線結尾。
* 只在名字中使用字母、數字和下底線。 * 只在名字中使用字母、數字和下底線。
* 不要再名字中出現連續下底線——這樣很難辨認。 * 不要再名字中出現連續下底線——這樣很難辨認。
@ -61,26 +61,26 @@ SELECT first_name
FROM staff; FROM staff;
``` ```
### Tables 表名 ### 表格Tables
* 用集合名詞,或在不那麽理想的情況下,複數形式。如`staff`和`employees` * 用集合名詞,或在不那麽理想的情況下,複數形式。如 `staff``employees`
* 不要使用類似`tbl`或其他的描述性的前綴或匈牙利命名法。 * 不要使用類似 `tbl` 或其他的描述性的前綴或匈牙利命名法。
* 表不應該同它的列同名,反之亦然。 * 表不應該同它的列同名,反之亦然。
* 盡量避免連接兩個表的名字作為關系表relationship table的名字。與其使用`cars_mechanics`做表名不如使用`services`。 * 盡量避免連接兩個表的名字作為關系表relationship table的名字。與其使用 `cars_mechanics` 做表名不如使用 `services`
### Columns 列名 ### 欄位名Columns
* 總是使用單數形式。 * 總是使用單數形式。
* 避免直接使用`id`做表的主標識符。 * 避免直接使用 `id` 做表的主標識符。
* 避免列名同表名同名,反之亦然。 * 避免列名同表名同名,反之亦然。
* 總是使用小寫字母,除非是特殊情況,如專有名詞。 * 總是使用小寫字母,除非是特殊情況,如專有名詞。
### Aliasing or correlations 別名與關聯名 ### 別名與關聯名Aliasing or correlations
* 應該與它們別名的對象或與它們代表的表達式相關聯。 * 應該與它們別名的對象或與它們代表的表達式相關聯。
* 一般來說,關聯名應該是對象名的第一個字母。 * 一般來說,關聯名應該是對象名的第一個字母。
* 如果已經有相同的關聯名了,那麽在關聯名後加一個數字。 * 如果已經有相同的關聯名了,那麽在關聯名後加一個數字。
* 總是加上`AS`關鍵字,因為這樣的顯示聲明易於閱讀。 * 總是加上 `AS` 關鍵字,因為這樣的顯示聲明易於閱讀。
* 為計算出的數據命名時,用一個將這條數據存在表裏時會使用的列名。 * 為計算出的數據命名時,用一個將這條數據存在表裏時會使用的列名。
```sql ```sql
@ -94,14 +94,14 @@ SELECT SUM(s.monitor_tally) AS monitor_total
FROM staff AS s; FROM staff AS s;
``` ```
### Stored procedures 過程名 ### 預存程序Stored procedures
* 名字一定要包含動詞。 * 名字一定要包含動詞。
* 不要附加`sp_`或任何其他這樣的敘述性前綴或使用匈牙利表示法。 * 不要附加 `sp_` 或任何其他這樣的敘述性前綴或使用匈牙利表示法。
### Uniform suffix 統一的後綴 ### 統一的後綴Uniform suffix
下列後綴有統一的意義,能保證SQL代碼更容易被理解。在合適的時候使用正確的後綴。 下列後綴有統一的意義,能保證 SQL 程式碼更容易被理解。在合適的時候使用正確的後綴。
* `_id` 獨一無二的標識符,如主鍵。 * `_id` 獨一無二的標識符,如主鍵。
* `_status` 標識值或任何表示狀態的值,比如`publication_status`。 * `_status` 標識值或任何表示狀態的值,比如`publication_status`。
@ -112,17 +112,17 @@ SELECT SUM(s.monitor_tally) AS monitor_total
* `_date` 表示該列包含日期。 * `_date` 表示該列包含日期。
* `_tally` 計數值。 * `_tally` 計數值。
* `_size` 大小,如文件大小或服裝大小。 * `_size` 大小,如文件大小或服裝大小。
* `_addr` 地址,有形的或無形的,如`ip_addr` * `_addr` 地址,有形的或無形的,如 `ip_addr`
## Query syntax 查詢語句 ## 查詢語句Query syntax
### Reserved words 保留字 ### 保留字Reserved words
保留字總是大寫,如`SELECT`和`WHERE` 保留字總是大寫,如 `SELECT``WHERE`
最好使用保留字的全稱而不是簡寫,用`ABSOLUTE`而不用`ABS`。 最好使用保留字的全稱而不是簡寫,用 `ABSOLUTE` 而不用 `ABS`
當標準ANSI SQL關鍵字能完成相同的事情時不要使用資料庫伺服器相依的關鍵字這樣能增強可移植性。 當標準 ANSI SQL 關鍵字能完成相同的事情時,不要使用資料庫伺服器相依的關鍵字,這樣能增強可移植性。
```sql ```sql
SELECT model_num SELECT model_num
@ -130,13 +130,13 @@ SELECT model_num
WHERE p.release_date > '2014-09-30'; WHERE p.release_date > '2014-09-30';
``` ```
### White space 空白字元 ### 空白字元White space
正確地使用空白字元對清晰的代碼十分重要。不要把代碼堆在一起或移除自然語言中的空格。 正確地使用空白字元對清晰的程式碼十分重要。不要把程式碼堆在一起或移除自然語言中的空格。
#### Spaces 空格 #### 空格Spaces
用空格使根關鍵字都結束在同一列上。在代碼中形成一個從上到下的“川流”,這樣幫助讀者快速掃描代碼並將關鍵字和實現細節分開。川流在排版時應該避免但是對書寫SQL語句是有幫助的。 用空格使根關鍵字都結束在同一列上。在程式碼中形成一個從上到下的「川流」,這樣幫助讀者快速掃描程式碼並將關鍵字和實做細節分開。川流在排版時應該避免,但是對書寫 SQL 語句是有幫助的。
```sql ```sql
(SELECT f.species_name, (SELECT f.species_name,
@ -158,9 +158,9 @@ SELECT model_num
GROUP BY b.species_name, b.observation_date); GROUP BY b.species_name, b.observation_date);
``` ```
注意`WHERE`和`FROM`等關鍵字,都右對齊,而真實的列名都左對齊。 注意 `WHERE``FROM` 等關鍵字,都靠右對齊,而真實的列名都靠左對齊。
注意下列情況總是加入空格 下列是需要加入空格的情況
* 在等號前後(`=` * 在等號前後(`=`
* 在逗號後(`,` * 在逗號後(`,`
@ -173,17 +173,17 @@ SELECT a.title, a.release_date, a.recording_date
OR a.title = 'The New Danger'; OR a.title = 'The New Danger';
``` ```
#### Line spacing 換行 #### 換行Line spacing
總是換行的情況 必需換行的時機
* 在`AND`或`OR`前。 * 在`AND`或`OR`前。
* 在分號後(分隔語句以提高可讀性)。 * 在分號後(分隔語句以提高可讀性)。
* 在每個關鍵定以後。 * 在每個關鍵定以後。
* 將多個列組成一個邏輯組時的逗號後。 * 將多個列組成一個邏輯組時的逗號後。
* 將代碼分隔成相關聯的多個部分,幫助提高大段代碼的可讀性。 * 將程式碼分隔成相關聯的多個部分,幫助提高大區塊程式碼的可讀性。
讓所有的關鍵字右對齊,讓所有的值左對齊,在查詢語句中間留出一個空隙。這樣能提高速讀代碼的速讀 將所有的關鍵字右對齊,將所有的值靠左對齊,並在查詢語句中間留出一個空隙。這樣能提高程式碼的閱讀速度
```sql ```sql
@ -206,13 +206,13 @@ SELECT a.title,
OR a.title = 'The New Danger'; OR a.title = 'The New Danger';
``` ```
### Identation 縮排 ### 縮排Indentation
為確保SQL的可讀性一定要遵守下列規則。 為確保 SQL 的可讀性,務必要遵守下列規則。
### Joins Join語句 ### Join 語句
Join語句應該縮進到川流的另一側並在必要的時候添加一個換行。 Join 語句應該縮進到川流的另一側並在必要的時候加入換行。
```sql ```sql
@ -227,7 +227,7 @@ SELECT r.last_name
AND c.chief = 'Y'; AND c.chief = 'Y';
``` ```
#### Subqueries 子查詢 #### 子查詢Subqueries
子查詢應該在川流的右側對齊並使用其他查詢相同的樣式。有時候將右括號單獨置於一行並同與它配對的左括號對齊是有意義的——尤其是當存在嵌套子查詢的時候。 子查詢應該在川流的右側對齊並使用其他查詢相同的樣式。有時候將右括號單獨置於一行並同與它配對的左括號對齊是有意義的——尤其是當存在嵌套子查詢的時候。
@ -245,12 +245,12 @@ SELECT r.last_name,
AND c.confirmed = 'Y'); AND c.confirmed = 'Y');
``` ```
### Preferred formalisms 推薦的形式 ### 推薦的形式Preferred formalisms
* 盡量使用`BETWEEN`而不是多個`AND`語句。 * 盡量使用 `BETWEEN` 而不是多個 `AND` 語句。
* 同樣地,使用`IN()`而不是多個`OR`語句。 * 同樣地,使用 `IN()` 而不是多個 `OR` 語句。
* 當數據輸出資料庫時需要處理時,使用`CASE`表達式。`CASE`語句能嵌套形成更覆雜的邏輯結構。 * 當數據輸出資料庫時需要處理時,使用 `CASE` 表達式。`CASE` 語句能嵌套形成更覆雜的邏輯結構。
* 盡量避免`UNION`語句和臨時表。如果資料庫架構能夠不靠這些語句運行,那麽多數情況下它就不應該依靠這些語句。 * 盡量避免 `UNION` 語句和臨時表。如果資料庫架構能夠不依賴這些語句運行,那麽多數情況下它就不應該依賴這些語句。
```sql ```sql
@ -264,62 +264,62 @@ SELECT CASE postcode
AND postcode IN ('EH1', 'BN1', 'NN1', 'KW1'); AND postcode IN ('EH1', 'BN1', 'NN1', 'KW1');
``` ```
## Create syntax 創建語句 ## 建立語句Create syntax
聲明模式信息時維護可讀碼也很重要。所以列定義的順序和分組一定要有意義。 聲明模式信息時維護可讀程式碼也很重要。所以列定義的順序和分組一定要有意義。
`CREATE`定義中每列要縮排4個空格。 `CREATE` 語句中,其後每列要縮排 4 個空格。
### Choosing data types 選擇數據類型 ### 選擇數據類型Choosing data types
* 盡可能避免使用供應商特定的數據類型。 它們不僅不可移植,而且可能不適用於相同供應商軟體的舊版本 * 盡可能避免使用特定廠商的資料類型。 它們不僅不可移植,而且可能不適用於相同廠商的舊版軟體
* 只在真的需要浮點數運算的時候才使用`REAL`和`FLOAT`類型,否則使用`NUMERIC`和`DECIMAL`類型。浮點數舍入誤差是個麻煩 * 只在真的需要浮點數運算的時候才使用 `REAL``FLOAT` 類型,否則使用 `NUMERIC``DECIMAL` 類型。浮點數進位誤差是個問題
### Specifying default values 指定預設類型 ### 指定預設類型Specifying default values
* 預設值一定與列的類型相同——如果一個列的類型是`DECIMAL`那麽就不要使用`INTEGER`類型作為預設值。 * 預設值一定與列的類型相同——如果一個列的類型是 `DECIMAL` 那麽就不要使用 `INTEGER` 類型作為預設值。
* 預設值要緊跟類型聲明並在`NOT NULL`聲明前。 * 預設值要緊跟類型聲明並在 `NOT NULL` 聲明前。
### Constraints and keys 約束和鍵 ### 約束和鍵Constraints and keys
約束和鍵是構成資料庫系統的重要組成部分。它們能很快地變得難以閱讀和理解,所以遵從指南方針是很重要的。 約束Constraints和鍵key是構成資料庫系統的重要組成部分。它們能很快地變得難以閱讀和理解,所以遵從指南方針是很重要的。
#### Choosing keys 選擇鍵 #### 選擇鍵Choosing keys
設計時應該謹慎選擇構成鍵的列,因為鍵既明顯影響著性能和數據完整性。 設計時應該謹慎選擇構成鍵的列,因為鍵既明顯影響著性能和數據完整性。
1. 鍵在某種程度上應該是獨一無二的。 1. 鍵在某種程度上應該是獨一無二的。
2. 該值在不同表中的類型應該相同並且盡量不會更改。 2. 該值在不同表中的類型應該相同並且盡量不會更改。
3. 該值是否會無法通過某些標準格式如ISO發布的標準 遵守第2點。 3. 該值是否會無法通過某些標準格式(如 ISO 發布的標準)? 遵守第2點。
4. 盡量讓鍵保持簡單,但在適當情況下不要害怕使用複合鍵。 4. 盡量讓鍵保持簡單,但在適當情況下不要害怕使用複合鍵。
以上是定義資料庫時合乎邏輯的平衡做法。當需求變更時,鍵也應該根據情況更新。 以上是定義資料庫時合乎邏輯的平衡做法。當需求變更時,鍵也應該根據情況更新。
#### Defining constraints 定義約束 #### 定義約束Defining constraints
確定鍵後,就可以用約束和字值段驗證來定義它們。 確定鍵後,就可以用約束和字值段驗證來定義它們。
##### General 概述 ##### 概要General
* 表至少需要一個鍵來保證其完整性和可用性。 * 表至少需要一個鍵來保證其完整性和可用性。
* 約束應該有名字,除了`UNIQUE`、`PRIMARY KEY`和`FOREIGN KEY`之外。 * 約束應該有名字,除了 `UNIQUE`、`PRIMARY KEY` 和 `FOREIGN KEY` 之外。
##### Layout and order 布局和順序 ##### 布局和順序Layout and order
* 在`CREATE TABLE`語句後先定義主鍵。 * 在 `CREATE TABLE` 語句後先定義主鍵。
* 約束的定義應該緊跟它相應的列的定義後。 * 約束的定義應該緊跟它相應的列的定義後。
* 如果該約束與多個列相關,那麽讓它盡量離與其相關的列距離越近越好。實在不行就講它放在表定義的最後。 * 如果該約束與多個列相關,那麽讓它盡量離與其相關的列距離越近越好。實在不行就講它放在表定義的最後。
* 如果是與整個表相關聯表級別的約束,那麽就將放在表的定義的最後。 * 如果是與整個表相關聯表級別的約束,那麽就將放在表的定義的最後。
* 按照字母順序安排定義,`ON DELETE`排在`ON UPDATE`前。 * 按照字母順序安排定義,`ON DELETE` 排在 `ON UPDATE` 前。
* 必要的話,把所有相關的語句對齊。比如,把所有`NOT NULL`定義對齊到同一列。雖然這樣的做法有些慢,但是能提高可讀性。 * 必要的話,把所有相關的語句對齊。比如,把所有 `NOT NULL` 定義對齊到同一列。雖然這樣的做法有些慢,但是能提高可讀性。
##### Validation 校驗 ##### 校驗Layout and order
* 用`LIKE`和`SIMILAR TO`約束來保證格式已知字串的數據完整性。 * 用 `LIKE``SIMILAR TO` 約束來保證格式已知字串的數據完整性。
* 當數字的值的範圍可以確定時,用`CHECK()`來防止錯誤的值進入資料庫或被錯誤地轉換。在大部分情況下,至少要確認該值大於零。 * 當數字的值的範圍可以確定時,用 `CHECK()` 來防止錯誤的值進入資料庫或被錯誤地轉換。在大部分情況下,至少要確認該值大於零。
* `CHECK()`約束應該在單獨的語句中以便debug * `CHECK()` 約束應該在單獨的語句中以便偵錯
##### Example ##### 範例
```sql ```sql
CREATE TABLE staff ( CREATE TABLE staff (
@ -332,19 +332,19 @@ CREATE TABLE staff (
); );
``` ```
### Design to avoid ### Designs to avoid
* 物件導向程式設計並不適用於關聯式資料庫——避免這個陷阱。 * 物件導向程式設計並不適用於關聯式資料庫——避免這個陷阱。
* 將值存入一列並將單位存在另一列。列的定義應該讓自己的單位不言自明以避免在應用內進行合並。使用`CHECK()`來保證資料庫中的數據是合法的。 * 將**值**保存在一個欄位並將**單位**保存在另一個欄位。欄位的定義應該讓自己的單位不言自明以避免在應用程式內進行合並。使用`CHECK()`來保證資料庫中的數據是有效的。
* [EAV (Entity Attribute Value)][eav]表——用特殊的產品來處理無模式數據。 * [EAV (Entity Attribute Value)][eav]表——用特殊的產品來處理無模式數據。
* 因為某些原因(如為了歸檔、為了劃分跨國公司的區域)將能合並在一起的表分開。這樣的設計導致以後必須使用`UNION`操作而不能直接查詢一個表。 * 因為某些原因(如為了歸檔、為了劃分跨國公司的區域)將能合並在一起的表分開。這樣的設計導致以後必須使用 `UNION` 操作而不能直接查詢一個表。
## 附錄 ## 附錄
### 保留字參考 ### 保留字參考
下表包含了ANSI SQL (92, 99 和 2003)、MySQL 3到5.x、PostgreSQL 8.1、MS SQL Server 2000、MS ODBC和Oracle 10.2中的關鍵字。 下表包含了 ANSI SQL92, 99 和 2003、MySQL 3 到 5.x、PostgreSQL 8.1、MS SQL Server 2000、MS ODBC 和 Oracle 10.2 中的關鍵字。
```sql ```sql
A A