Beaver's Blog

Freedom Openness Inclusion

0%

SQL代码规范

前言

本来想给这篇文章叫SQL编程规范的,感觉大家有把SQL当作编程语言吗?索性叫SQL代码规范好了,废话不多说,下面开始说一下SQL的代码风格。

对于很多的编程语言来说,大家总有个人的或者通用的代码风格,其实这对于SQL同样也不例外。好的代码风格可以提高代码的可读性,降低维护成本。有些编程语言(如Golang)内置了格式化代码命令gofmt,可以非常方便的格式化代码。对于代码的风格,大家的看法总是不尽相同,每个人可能都有自己的风格,如何缩进,怎么变量命名等等。当一种代码规范形成一种共识后,我想这才能最大程度上提高代码的可读性、可维护性。

SQL需要有代码规范吗

正如上面所说,好的代码风格可以提高代码的可读性。其实,SQL作为一种被经常使用的语言,好的代码规范对SQL使用来说非常重要。我见过很多SQL代码写的很漂亮的,读起来让人赏心悦目;也见过很多糟糕的SQL代码,这种糟糕的代码,让我一半的时间都在理解这到底写的什么。所以,我们也要对SQL的代码规范重视起来,就像重视其他编程语言代码规范那样。

SQL的代码规范

我根据自己的喜好及大家经常使用的规范,整理了一份SQL规范,仅供参考。

编码总体原则

  • SQL语句应正确、规范、高效
  • 应避免写较为复杂的SQL语句
  • 代码要整体层次分明及结构化
  • 代码中应有必要的注释以增强代码的可读性
  • 代码应充分考虑数据库性能
  • 使用SELECT语句时,应指出列名,不应使用列的序号或者用“*”替代所有列名
  • 如果 SQL 语句连接多表时,应使用表的别名来引用列

根据编码总体原则,详细说一下SQL的代码规范。

大小写

SQL中的关键字、内置函数应大写,其余部分(列名、别名、表名等)应小写,以便于理解。不应该出现大小写混着写的情况。

SQL常见的关键字:SELECT,UPDATE,DELETE,INSERT,WHERE,CASE WHEN END,AS,INTO,GROUP BY,HAVING等。

1
2
3
4
5
6
-- good sql
SELECT id FROM t
SELECT id, COUNT(1) cnt FROM t GROUP BY id HAVING COUNT(1)>1
-- bad sql
select ID from T
Select Id From T

指定列名

无论是对于查询,插入还是排序等操作,都应指定列名。

  • 查询

    查询时应避免使用*代替所有列,只指定使用的列名。

    1
    2
    3
    4
    -- Good sql
    SELECT C1, C2 FROM T;
    -- Bad sql
    SELECT * FROM T
  • 插入

    使用INSERT语句插入数据时,也应指定列名。当然,插入数据时,我们会指定列名,不然数据可能插入到别的字段。

  • 排序、分组

    排序、分组也应遵循指定列名

    1
    2
    3
    4
    -- Good sql
    SELECT C1, C2 FROM T ORDER BY C1, C2;
    -- Bad sql
    SELECT C, C2 FROM T ORDER BY 1, 2;

注释

好的SQL编码会添加注释,以提高可读性。对于SQL的注释做以下规范:

  • 每条SQL语句均应添加注释说明;
  • 每条SQL语句的注释单独成行,并放在语句的前面;
  • 字段注释紧跟在字段后面;
  • 对不易理解的分支条件表达式应添加注释,便于理解;
  • 对重要的计算添加注释,以说明其功能。

命名

SQL中不像其他其他编程语言中,需要大量对变量、函数等对象命名,但是这不意味着命名在写SQL中不重要。sql中有命名情况的有:列别名、表别名、子查询别名等,命名应具有实际的含义且应小写,避免使用中文。太长的命名应使用_隔开,例如:thisIsAColumn,应该这么写this_is_a_column,以提高可读性。

1
2
3
4
5
6
7
8
9
10
11
-- Good sql
SELECT COUNT(C1) AS cnt
FROM T t
LEFT JOIN (
SELECT id,name
FROM T2
) t3 ON t.id = t3.id
WHERE t.id > 100
-- Bad sql
SELECT COUNT(1) as 总数
FROM T t LEFT JOIN (SELECT id FROM t2) t3 ON t.id = t3.id

字段排列

SQL中字段应在SELECT后另起一行,且排列应保持对齐,过滤语句中使用了ANDOR,应另起一行。

1
2
3
4
5
6
7
8
9
10
11
12
SELECT	
C1,
C2,
C3
FROM t
LEFT JOIN t2
ON t.id=t2.id
WHERE t.id > 100
AND t.name LIKE '%any'
GROUP BY
t.id,
t2.name

CASE语句

CASE语句用于SQL中字表达式值的判断,对于CASE语句的代码规范做以下约定:

1
2
3
4
5
6
7
CASE WHEN t.id >= 90 THEN 'Great'
WHEN t.id >= 60 THEN 'OK'
ELSE 'Bad' END AS column_x,
-- 另一种CASE写法
CASE expr WHEN r1 THEN ...
WHEN r2 THEN ...
END NULL END AS column_x,

多表关联

sql中多表关联是很常见的,但是对于多表关联的表应使用别名,避免使用产生笛卡尔积的关联操作。关联条件的ON应另起一行且使用缩进。

1
2
3
4
5
6
7
8
9
-- Good sql
SELECT t.id, t.name, t2.score
FROM table1 t
INNER JOIN table2 t2
ON t.id = t2.id
-- Bad sql
SELECT t.id, t.name, t2.score
FROM table1 t, table2 t2
WHERE t.id = t2.id

嵌套子查询

SQL中应避免写过于复杂的嵌套子查询,子查询语句应层次分明,结构化强。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SELECT 
t.id,
t.name,
t.address
FROM table1 t
WHERE t.id > 100
AND t.name IN (
SELECT
t2.name
FROM table2 t2
LEFT JOIN table3 t3
ON t2.id = t3.id
WHERE t2.socre > 90
)
AND t.address NOT IN (
SELECT
address
FROM table4 t4
WHERE t4.address_status = 'False'
)
ORDER BY t.id

数据库性能

SQL编码应考虑数据库性能,考虑执行速度最优原则,SQL代码应尽量使用索引,避免全表扫描,提高数据库性能。

SQL很常见,使用的人群也很广,但也应该重视SQL的编码规范。

References

[1] SQL代码编码原则和规范 - DataWorks - 阿里云

[2] Gitlab: SQL Style Guide