《SQL开发样式指南》,让你的SQL代码更加规范
点击关注上方“SQL数据库开发”,
设为“置顶或星标”,第一时间送达干货
General Theory 一般原则
Do 应该做的事情
使用一致的、叙述性的名称。 灵活使用空格和缩进来增强可读性。 存储符合ISO-8601标准的日期格式( YYYY-MM-DD HH:MM:SS.SSSSS
)。最好使用标准SQL函数而不是特定供应商的函数以提高可移植性。 保证代码简洁明了并消除多余的SQL——比如非必要的引号或括号,或者可以推导出的多余 WHERE
语句。必要时在SQL代码中加入注释。优先使用C语言式的以 /*
开始以*/
结束的块注释,或使用以--
开始的行注释。
Avoid 应避免的事情
驼峰命名法——它不适合快速扫描。 描述性的前缀或匈牙利命名法比如 sp_
或tbl
。复数形式——尽量使用更自然的集合术语。比如,用“staff”替代“employees”,或用“people”替代“individuals”。 需要引用号的标识符——如果你必须使用这样的标识符,最好坚持用SQL92的双引号来提高可移植性。 面向对象编程的原则不该应用到结构化查询语言或数据库结构上。
Naming conventions 命名惯例
General 一般原则
保证名字独一无二且不是保留字。 保证名字长度不超过30个字节。 名字要以字母开头,不能以下划线结尾。 只在名字中使用字母、数字和下划线。 不要在名字中出现连续下划线——这样很难辨认。 在名字中需要空格的地方用下划线代替。 尽量避免使用缩写词。使用时一定确定这个缩写简明易懂。
Tables 表名
用集群名称,或在不那么理想的情况下,复数形式。如 staff
和employees
。不要使用类似 tbl
或其他的描述性的前缀或匈牙利命名法。表不应该同它的列同名,反之亦然。 尽量避免连接两个表的名字作为关系表(relationship table)的名字。与其使用 cars_mechanics
做表名不如使用services
。
Columns 列名
总是使用单数形式。 避免直接使用 id
做表的主标识符。避免列名同表名同名,反之亦然。 总是使用小写字母,除非是特殊情况,如专有名词。
Aliasing or correlations 别名与关联名
应该与它们别名的对象或与它们代表的表达式相关联。 一般来说,关联名应该是对象名的第一个字母。 如果已经有相同的关联名了,那么在关联名后加一个数字。 总是加上 AS
关键字,因为这样的显示声明易于阅读。为计算出的数据命名时,用一个将这条数据存在表里时会使用的列名。
Stored procedures 过程名
名字一定要包含动词。 不要附加 sp_
或任何其他这样的叙述性前缀或使用匈牙利表示法。
Uniform suffix 统一的后缀
_id
独一无二的标识符,如主键。_status
标识值或任何表示状态的值,比如publication_status
。_total
总和或某些值的和。_num
表示该域包含数值。_name
表示名字。_seq
包含一系列数值。_date
表示该列包含日期。_tally
计数值。_size
大小,如文件大小或服装大小。_addr
地址,有形的或无形的,如ip_addr
Query syntax 查询语句
Reserved words 保留字
SELECT
和WHERE
。ABSOLUTE
而不用ABS
。White space 空白字符
Spaces 空格
WHERE
和FROM
等关键字,都右对齐,而真实的列名都左对齐。在等号前后( =
)在逗号后( ,
)单引号前后( '
),除非单引号后面是括号、逗号或分号
Line spacing 换行
在 AND
或OR
前。在分号后(分隔语句以提高可读性)。 在每个关键词定以后。 将多个列组成一个逻辑组时的逗号后。 将代码分隔成相关联的多个部分,帮助提高大段代码的可读性。
Identation 缩进
Joins Join语句
Subqueries 子查询
Preferred formalisms 推荐的形式
尽量使用 BETWEEN
而不是多个AND
语句。同样地,使用 IN()
而不是多个OR
语句。当数据输出数据库时需要处理时,使用 CASE
表达式。CASE
语句能嵌套形成更复杂的逻辑结构。尽量避免 UNION
语句和临时表。如果数据库架构能够不靠这些语句运行,那么多数情况下它就不应该依靠这些语句。
Create syntax 创建语句
CREATE
定义中,每列要缩进4个空格。Choosing data types 选择数据类型
尽量不使用供应商相关的数据类型——这些类型可不能能在老系统上使用。 只在真的需要浮点数运算的时候才使用 REAL
和FLOAT
类型,否则使用NUMERIC
和DECIMAL
类型。浮点数舍入误差是个麻烦。
Specifying default values 指定默认类型
默认值一定与列的类型相同——如果一个列的类型是 DECIMAL
那么就不要使用INTEGER
类型作为默认值。默认值要紧跟类型声明并在 NOT NULL
声明前。
Choosing keys 选择键
键在某种程度上应该是独一无二的。 该值在不同表中的类型应该相同并且尽量不会更改。 该值是否会无法通过某种标准格式(如ISO发布的标准)?如 尽量让键保持简单,但在适当情况下不要害怕使用复合键。
Defining constraints 定义约束
General 概述
表至少需要一个键来保证其完整性和可用性。 约束应该有名字,除了 UNIQUE
、PRIMARY KEY
和FOREIGN KEY
之外。
Layout and order 布局和顺序
在 CREATE TABLE
语句后先定义主键。约束的定义应该紧跟它相应的列的定义后。 如果该约束与多个列相关,那么让它尽量离与其相关的列距离越近越好。实在不行就讲它放在表定义的最后。 如果是与整个表相关联表级别的约束,那么就将放在表的定义的最后。 按照字母顺序安排定义, ON DELETE
排在ON UPDATE
前。有道理的话,把所有相关的语句对齐。比如,把所有 NOT NULL
定义对齐到同一列。虽然这样的做法有些慢,但是能提高可读性。
Validation 校验
用 LIKE
和SIMILAR TO
约束来保证格式已知字符串的数据完整性。当数字的值的范围可以确定时,用 CHECK()
来防止错误的值进入数据库或被错误地转换。大部分情况下至少要确认值要大于零。CHECK()
约束应该在单独的语句中以便debug。
Example:
Design to avoid
面向对象设计思想并不适用于关系型数据库——避免这个陷阱。 将值存入一列并将单位存在另一列。列的定义应该让自己的单位不言自明以避免在应用内进行合并。使用 CHECK()
来保证数据库中的数据是合法的。EAV (Entity Attribute Value)表——用特殊的产品来处理无模式数据。 因为某些原因(如为了归档、为了划分跨国公司的区域)将能合并在一起的表分开。这样的设计导致以后必须使用 UNION
操作而不能直接查询一个表。
——End——
后台回复关键字:1024,获取一份精心整理的技术干货 后台回复关键字:进群,带你进入高手如云的交流群。 推荐阅读 这是一个能学到技术的公众号,欢迎关注
点击「阅读原文」了解SQL训练营
评论