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

improve Simplified Chinese translation

This commit is contained in:
rhanqtl 2020-04-29 11:07:14 +08:00
parent 370a1941df
commit 8485b3db33

View file

@ -1,14 +1,14 @@
# SQL style guide SQL 样式指南
这篇文档翻译自以[署名-相同方式共享 4.0 国际协议][licence-zh]发布的[http://www.sqlstyle.guide][sqlstyleguide],译文以原文同样的协议发布。
这篇文档翻译自以[署名-相同方式共享 4.0 国际协议][licence-zh]发布的 [http://www.sqlstyle.guide][sqlstyleguide],译文以原文同样的协议发布。
## Overview 综述
你可以直接使用这些指导方针,或者[fork][fork]后创建自己的版本——最重要的是选择一套方针并严格遵守它。欢迎通过提交[issue][issue]或[pull request][pull]来提交建议或修复bug。
你可以直接使用这些指导方针,或者 [fork][fork] 后创建自己的版本 —— 最重要的是选择一套方针并严格遵守它。欢迎通过在 GitHub 上提交 [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 格式][dl-md] 添加到项目代码库中或将该页面的链接发送给项目的所有参与者要比传阅实体书容易得多。
[Simon Holywell][simon] 所著的《SQL 样式指南》以[署名-相同方式共享 4.0 国际协议][licence-zh]发布,改编自 [http://www.sqlstyle.guide][sqlstyleguide]。
@ -16,12 +16,12 @@
### Do 应该做的事情
* 使用一致的、述性的名称。
* 灵活使用空格和缩进来增强可读性。
* 存储符合[ISO-8601][iso-8601]标准的日期格式(`YYYY-MM-DD HH:MM:SS.SSSSS`)
* 最好使用标准SQL函数而不是特定供应商的函数以提高可移植性
* 保证代码简洁明了并消除多余的SQL——比如非必要的引号或括号或者可以推导出的多余`WHERE`语句。
* 必要时在SQL代码中加入注释。优先使用C语言式的以`/*`开始以`*/`结束的块注释,或使用以`--`开始的行注释
* 使用一致的、述性的名称。
* 合理地使用空格和缩进来增强可读性。
* 存储符合 [ISO-8601][iso-8601] 标准的日期格式(`YYYY-MM-DD HH:MM:SS.SSSSS`
* 为了提高可移植性,最好使用标准 SQL 函数而不是特定供应商的函数。
* 保证代码简洁明了、没有多余的 SQL —— 比如非必要的引号或括号,或者可以推导出的 `WHERE`句。
* 必要时在 SQL 代码中加入注释。优先使用 C 语言式的以 `/*` 开始以 `*/` 结束的块注释,或使用以 `--` 开始的行注释,并在末尾换行
```sql
SELECT file_hash -- stored ssdeep hash
@ -38,22 +38,22 @@ UPDATE file_system
### Avoid 应避免的事情
* 驼峰命名法——它不适合快速扫描
* 驼峰命名法 —— 它不适合快速扫读
* 描述性的前缀或匈牙利命名法比如 `sp_``tbl`
* 复数形式 —— 尽量使用更自然的集合术语。比如用“staff”替代“employees”或用“people”替代“individuals”。
* 需要引用号的标识符——如果你必须使用这样的标识符最好坚持用SQL92的双引号来提高可移植性。
* 面向对象编程的原则不该应用到结构化查询语言或数据库结构上。
* 被引号包裹的标识符quoted identifier—— 如果你必须使用这样的标识符,最好坚持用 SQL92 的双引号来提高可移植性(你可能需要配置你的 SQL 服务器以支持此特性,具体取决于供应商)
* 面向对象编程的原则不该应用到 SQL 或数据库结构上。
## Naming conventions 命名惯例
### General 一般原则
* 保证名字独一无二且不是[保留字][reserved-keywords]。
* 保证名字长度不超过30个字节。
* 保证名字长度不超过 30 个字节 —— 实际上,如果你不使用多字节字符集,就是 30 个字符
* 名字要以字母开头,不能以下划线结尾。
* 只在名字中使用字母、数字和下划线。
* 不要在名字中出现连续下划线 —— 这样很难辨认。
* 在名字中需要空格的地方用下划线代替。
* 在名字中需要空格的地方用下划线代替`first name` 变为 `first_name`
* 尽量避免使用缩写词。使用时一定确定这个缩写简明易懂。
```sql
@ -63,7 +63,7 @@ SELECT first_name
### Tables 表名
* 用集群名称,或在不那么理想的情况下,复数形式。如`staff`和`employees`
* 使用集合名称,或在不那么理想的情况下使用复数形式。如 `staff`(建议使用)和 `employees`
* 不要使用类似 `tbl` 或其他的描述性的前缀或匈牙利命名法。
* 表不应该同它的列同名,反之亦然。
* 尽量避免连接两个表的名字作为关系表relationship table的名字。与其使用 `cars_mechanics` 做表名不如使用 `services`
@ -72,16 +72,16 @@ SELECT first_name
* 总是使用单数形式。
* 避免直接使用 `id` 做表的主标识符。
* 避免列名表名同名,反之亦然。
* 避免列名表名同名,反之亦然。
* 总是使用小写字母,除非是特殊情况,如专有名词。
### Aliasing or correlations 别名与关联名
* 应该与它们别名的对象或与它们代表的表达式相关联。
* 一般来说,关联名应该是对象名的第一个字母
* 别名应该与它们所指的对象或表达式相关联。
* 一般来说,关联名应该由对象名中每一个单词的首字母组成
* 如果已经有相同的关联名了,那么在关联名后加一个数字。
* 总是加上`AS`关键字,因为这样的显示声明易于阅读。
* 为计算出的数据命名时,用一个将这条数据存在表里时会使用的列名。
* 总是加上 `AS` 关键字,因为这样的明确声明易于阅读。
* 为计算出的数据`SUM()` 或 `AVG()`)命名时,用一个将这条数据存在表中时会使用的列名。
```sql
SELECT first_name AS fn
@ -94,35 +94,35 @@ SELECT SUM(s.monitor_tally) AS monitor_total
FROM staff AS s;
```
### Stored procedures 过程名
### Stored procedures 存储过程名
* 名字一定要包含动词。
* 不要附加`sp_`或任何其他这样的叙述性前缀或使用匈牙利表示法。
* 不要附加 `sp_` 或任何其他这样的描述性的前缀或使用匈牙利表示法。
### Uniform suffix 统一的后缀
下列后缀有统一的意义能保证SQL代码更容易理解。在合适的时候使用正确的后缀。
下列后缀有统一的意义,能保证 SQL 代码更容易理解。在合适的时候使用正确的后缀。
* `_id` 独一无二的标识符,如主键。
* `_status` 标识值或任何表示状态的值,比如`publication_status`
* `_total` 总和或某些值的和。
* `_num` 表示该域包含数值。
* `_name` 表示名字。
* `_seq` 包含一系列值。
* `_date` 表示该列包含日期。
* `_tally` 计数值。
* `_size` 大小,如文件大小或服装大小。
* `_addr` 地址,有形的或无形的,如`ip_addr`
* `_id` —— 独一无二的标识符,如主键。
* `_status` —— 标志值或任何表示状态的值,比如 `publication_status`
* `_total` —— 总和或某些值的和。
* `_num` —— 表示该字段包含数值。
* `_name` —— 表示名字,例如 `first_name`
* `_seq` —— 包含一系列值。
* `_date` —— 表示该列包含日期。
* `_tally` —— 计数值。
* `_size` —— 大小,如文件大小或服装大小。
* `_addr` —— 地址,有形的或无形的,如 `ip_addr`
## Query syntax 查询语句
### Reserved words 保留字
保留字总是大写,如`SELECT`和`WHERE`
关键字总是大写,如 `SELECT``WHERE`
最好使用保留字的全称而不是简写,用`ABSOLUTE`而不用`ABS`
最好使用关键字的全称而不是简写,用 `ABSOLUTE` 而不用 `ABS`
当标准ANSI SQL关键字能完成相同的事情时不要使用数据库服务器相关的关键字,这样能增强可移植性。
当标准 ANSI SQL 关键字能完成相同的事情时,不要使用数据库服务器特定的关键字,这样能增强可移植性。
```sql
SELECT model_num
@ -132,11 +132,11 @@ SELECT model_num
### White space 空白字符
正确地使用空白字符对清晰的代码十分重要。不要把代码堆一起或移除自然语言中的空格。
正确地使用空白字符对清晰的代码十分重要。不要把代码堆一起或移除自然语言中的空格。
#### Spaces 空格
用空格使根关键字都结束在同一列上。在代码中形成一个从上到下的“川流”,这样帮助读者快速扫描代码并将关键字和实现细节分开。川流在排版时应该避免但是对书写SQL语句是有帮助的。
用空格使根关键字都结束在同一列上。在代码中形成一个从上到下的“川流”,这样帮助读者快速扫视代码并将关键字和实现细节分开。川流在排版时应该避免,但是对阅读 SQL 语句是有帮助的。
```sql
(SELECT f.species_name,
@ -158,13 +158,13 @@ SELECT model_num
GROUP BY b.species_name, b.observation_date);
```
注意`WHERE`和`FROM`等关键字,都右对齐,而真实的列名都左对齐。
注意 `SELECT``FROM` 等关键字,都右对齐,而实际的列名和实现细节都左对齐。
注意下列情况总是加入空格:
* 在等号前后`=`
* 在逗号`,`
* 单引号前后(`'`),除非单引号后面是括号、逗号或分号
* 在等号(`=`前后
* 在逗号(`,`
* 成对的单引号(`'`)前后,除非在括号中或后面是逗号 / 分号
```sql
SELECT a.title, a.release_date, a.recording_date
@ -177,13 +177,13 @@ SELECT a.title, a.release_date, a.recording_date
总是换行的情况:
* 在`AND`或`OR`前。
* 在分号后(分隔语句以提高可读性)
* 在每个关键词定以后。
* 将多个列组成一个逻辑组时的逗号后
* 将代码分隔成相关联的多个部分,帮助提高大段代码的可读性
* 在 `AND``OR`
* 在分号后(分隔语句以提高可读性)
* 在每个关键字定义之后
* 将多个列组成一个逻辑组时的逗号后
* 将代码分隔成相关联的多个部分,帮助提高大段代码的可读性
让所有的关键字右对齐,让所有的值左对齐,在查询语句中间留出一个空隙。这样能提高速读代码的速读
让所有的关键字右对齐、所有的值左对齐,这样就能在查询语句中间留出一个空隙,有助于快速扫读整个查询的定义
```sql
@ -200,17 +200,17 @@ UPDATE albums
```sql
SELECT a.title,
a.release_date, a.recording_date, a.production_date -- grouped dates together
a.release_date, a.recording_date, a.production_date -- 将所有的日期放在一起
FROM albums AS a
WHERE a.title = 'Charcoal Lane'
OR a.title = 'The New Danger';
```
### Identation 缩进
### Indentation 缩进
为确保 SQL 的可读性,一定要遵守下列规则。
### Joins Join语句
#### Joins Join 语句
Join 语句应该缩进到川流的另一侧并在必要的时候添加一个换行。
@ -268,16 +268,16 @@ SELECT CASE postcode
声明模式信息时维护可读代码也很重要。所以列定义的顺序和分组一定要有意义。
`CREATE`定义中每列要缩进4个空格。
`CREATE` 定义中,每个列定义要缩进 4 个空格。
### Choosing data types 选择数据类型
* 尽量不使用供应商相关的数据类型——这些类型可不能能在老系统上使用。
* 尽量不使用供应商相关的数据类型 —— 这些类型不可移植甚至有可能不能在相同供应商的旧版本系统上使用。
* 只在真的需要浮点数运算的时候才使用 `REAL``FLOAT` 类型,否则使用 `NUMERIC``DECIMAL` 类型。浮点数舍入误差是个麻烦。
### Specifying default values 指定默认类型
* 默认值一定与列的类型相同——如果一个列的类型是`DECIMAL`那么就不要使用`INTEGER`类型作为默认值。
* 默认值一定与列的类型相同 —— 如果一个列的类型是 `DECIMAL` 那么就不要使用 `INTEGER` 类型的值作为默认值。
* 默认值要紧跟类型声明并在 `NOT NULL` 声明前。
### Constraints and keys 约束和键
@ -286,11 +286,11 @@ SELECT CASE postcode
#### Choosing keys 选择键
设计时应该谨慎选择构成键的列,因为键既明显影响着性能和数据完整性。
设计时应该谨慎选择构成键的列,因为键会影响性能和数据完整性。
1. 键在某种程度上应该是独一无二的。
2. 该值在不同表中的类型应该相同并且尽量不会更改。
3. 该值是否会无法通过某种标准格式如ISO发布的标准
3. 该值能否通过某种标准格式(如 ISO 发布的标准)?鼓励与前面第二点一致。
4. 尽量让键保持简单,但在适当情况下不要害怕使用复合键。
以上是定义数据库时合乎逻辑的平衡做法。当需求变更时,键也应该根据情况更新。
@ -302,22 +302,22 @@ SELECT CASE postcode
##### General 概述
* 表至少需要一个键来保证其完整性和可用性。
* 约束应该有名字,除了`UNIQUE`、`PRIMARY KEY`和`FOREIGN KEY`之外
* 除了 `UNIQUE` 、`PRIMARY KEY` 和 `FOREIGN KEY` 之外(数据库供应商会提供相应的检查),约束应该有名字
##### Layout and order 布局和顺序
* 在 `CREATE TABLE` 语句后先定义主键。
* 约束的定义应该紧跟它相应的列的定义后。
* 如果该约束与多个列相关,那么让它尽量离与其相关的列距离越近越好。实在不行就讲它放在表定义的最后。
* 如果是与整个表相关联表级别的约束,那么就将放在表的定义的最后。
* 如果该约束与多个列相关,那么让它离相关的列越近越好。实在不行就将它放在表定义的最后。
* 如果是应用于整个表的表级别的约束,那么就将它放在表定义的最后。
* 按照字母顺序安排定义,`ON DELETE` 排在 `ON UPDATE` 前。
* 有道理的话,把所有相关的语句对齐。比如,把所有`NOT NULL`定义对齐到同一列。虽然这样的做法有些慢,但是能提高可读性。
* 有道理的话,把所有相关的语句对齐。比如,把所有 `NOT NULL` 定义对齐到同一列。这样做并不难,但是能提高可读性。
##### Validation 校验
* 用`LIKE`和`SIMILAR TO`约束来保证格式已知字符串的数据完整性。
* 当数字的值的范围可以确定时,用`CHECK()`来防止错误的值进入数据库或被错误地转换。大部分情况下至少要确认值要大于零。
* `CHECK()`约束应该在单独的语句中以便debug。
* 当字符串的格式已知时,用 `LIKE``SIMILAR TO` 约束来保证它们的完整性。
* 当数值的范围可以确定时,用范围 `CHECK()` 来防止错误的值进入数据库或在没有提示的情况下截断。大部分情况下至少要确认数值大于零。
* `CHECK()` 约束应该在单独的子句中以便 debug。
##### Example
@ -332,19 +332,19 @@ CREATE TABLE staff (
);
```
### Design to avoid
### Design to avoid 应该避免的设计
* 面向对象设计思想并不适用于关系型数据库——避免这个陷阱。
* 将值存入一列并将单位存在另一列。列的定义应该让自己的单位不言自明以避免在应用内进行合并。使用`CHECK()`来保证数据库中的数据是合法的。
* [EAV (Entity Attribute Value)][eav]表——用特殊的产品来处理无模式数据。
* 因为某些原因(如为了归档、为了划分跨国公司的区域)将能合并在一起的表分开。这样的设计导致以后必须使用`UNION`操作而不能直接查询一个表。
* 在关系型数据库的设计中应用面向对象设计思想(原则)—— 面向对象设计思想(原则)并不能很好地适用于关系型数据库的设计,避免这个陷阱。
* 将值存入一列并将其单位存在另一列 —— 列的定义应该让自己的单位不言自明以避免在应用内进行合并。使用 `CHECK()` 来保证插入的数据是合法的。
* [EAV (Entity Attribute Value)][eav] 表 —— 应该用专门的产品来处理这样的无模式数据。
* 因为某些原因(如为了根据时间归档、为了划分跨国组织的区域)将本应该放在一个表中的数据分到多个表中 —— 这样的设计导致以后必须使用 `UNION` 操作而不能直接查询一个表。
## 附录
### 保留字参考
下表包含了ANSI SQL (92, 99 和 2003)、MySQL 3到5.x、PostgreSQL 8.1、MS SQL Server 2000、MS ODBC和Oracle 10.2中的关键字。
下表包含了 ANSI SQL9299 和 2003)、MySQL 3 到 5.x、PostgreSQL 8.1、MS SQL Server 2000、MS ODBC 和 Oracle 10.2 中的关键字。
```sql
A
@ -1174,6 +1174,50 @@ ZEROFILL
ZONE
```
### Column data types 列的数据类型
出于在数据库引擎之间达到最大程度兼容的目的,下面是一些建议使用的列数据类型。
#### Character types 字符型
* CHAR
* CLOB
* VARCHAR
#### Numeric types 数值型
* 精确数值类型
* BIGINT
* DECIMAL
* DECFLOAT
* INTEGER
* NUMERIC
* SMALLINT
* 近似数值类型
* DOUBLE PRECISION
* FLOAT
* REAL
#### Datetime types 日期时间类型
* DATE
* TIME
* TIMESTAMP
#### Binary types 二进制类型
* BINARY
* BLOB
* VARBINARY
#### Additional types 其他类型
* Boolean
* INTERVAL
* XML
[simon]: https://www.simonholywell.com/?utm_source=sqlstyle.guide&utm_medium=link&utm_campaign=md-document
"SimonHolywell.com"
[issue]: https://github.com/treffynnon/sqlstyle.guide/issues