
# 数据库使用规范
#### **命名规范**
- 对象名（如库、表、索引等）长度应小于等于63字节，注意某些字符（如中文）可能占用多个字节。
- 对象名不要使用数据库保留关键字，不能以"pg"和数字开头。
- 数据库名称长度可在1～63个字符之间，由字母、数字、或下划线组成，不能包含其他特殊字符，不能以"pg"和数字开头，且不能和RDS for PostgreSQL系统库重名。RDS for PostgreSQL系统库包括postgres、template0、template1，系统库不支持修改。
 
#### **表设计规范**
- 表结构应当提前设计，避免经常变更表结构，如添加字段，修改数据类型等。
- 单表字段数量不应太多，建议不超过64。
- 需要定期清理数据的表，建议创建分区表，比如按时间分区，通过DROP或TRUNCATE对应的分区子表清理数据。
- 表字段应使用合适的数据类型，如不要使用字符类型存储数值或者日期数据。
- 使用数值类型时应注意精度和范围，使用时不要超过类型的限制。
- 表结构中字段定义的数据类型建议与应用程序中定义的数据类型保持一致，表之间字段校对规则一致，避免发生报错或出现无法使用索引的情况。
- 如果业务逻辑冗长，建议减少数据库和业务应用之间的交互次数，使用数据库存储过程（如 PL/pgSQL）或内置函数。PostgreSQL内置的PL/pgSQL函数语言提供处理复杂业务逻辑的功能。
 
#### **索引设计规范**
- 使用逻辑复制时，对需要进行逻辑复制的表设计主键或者唯一键。
- 使用外键时，一定要设置外键被删除或更新的动作，例如ON DELETE CASCADE。
- 在使用频繁（如查询、排序）的字段上创建索引。
- 对于固定条件的查询，建议创建并使用部分索引。
- 对于经常使用表达式作为查询条件的查询，建议创建并使用表达式索引。
- 索引也会占用存储，单表索引数量不宜太多，比如单列索引个数小于5，复合索引个数小于3。
- 对于线性顺序存储的数据（如流式数据、时间字段或自增字段），建议使用BRIN索引，减少索引的大小，加快数据插入速度。
- B-Tree索引字段至多2000字节，如果表中的字段超过2000字节需要新建索引，建议使用函数索引（例如哈希值索引）或分词索引。
- 避免使用全表扫描（大数据量扫描的数据分析除外），PostgreSQL几乎支持所有数据类型的索引（例如B-Tree、Hash、GIN、GiST、BRIN、RUM等）。
 
#### **SQL设计**
- 查询时用具体的字段列表代替 \* ，避免返回用不到的字段。
- 查询或比较字段是否为NULL时，只能使用IS NULL或IS NOT NULL条件。
- 查询条件中，尽量使用NOT EXISTS替代NOT IN。
- 聚合数据时，尽量使用UNION ALL代替UNION。
- 删除数据时，尽量使用TRUNCATE代替全表DELETE。
- 分批提交大事务中对数据的修改，防止事务提交或回滚时压力集中。
- 创建函数时，应该定义函数易变性分类为对它们合法的分类中最严格的种类，而不是选择默认的VOLATILE。VOLATILE类函数调用并发过高可能导致新连接无法接入。
- 不建议使用COUNT(列名)来替代COUNT(\*)，COUNT(\*)是SQL92定义的标准统计行数的语法，会统计NULL值（真实行数），而COUNT(列名)不会统计。
- 避免向客户端返回大数据量，若数据量过大，可能导致应用性能下降。
- 对于需要范围查询的场景，建议使用范围类型以及GiST索引，提高范围检索的查询性能。
- 如果业务经常访问较大结果集的数据，建议将数据聚合成1条，例如经常要按ID访问此ID的数据，建议定期按ID聚合数据，查询时返回的记录数越少响应越快。
- RDS for PostgreSQL 16.6、15.10、14.15、13.18、12.22及以后的版本不允许创建C语言函数。
 
#### **安全**
- 禁止将应用数据库对象所有者赋予"public"，必须赋予某个特定角色。
- 数据库密码应具备一定复杂度， 禁止使用简单密码。
- 应该为每个业务分配不同的数据库账号，禁止多个业务共用一个数据库账号。
- 访问对象时，显式指定对象所在的模式，避免误访问到其他模式下的同名对象。
- 业务中如果以schema/role为单位分配权限，创建readwrite/readonly账号分配权限时遵循最小授权原则。
 
