Bytebase 成为 CNCF Landscape 上第一个被收录到 Database CI/CD 领域的项目 现在查看

SQL 审核规则

SQL 审核规则在线生成工具

PostgreSQL SQL 审核指南

进阶模板

为您的数据库提供全面保护和最佳实践。

基础模板

保证变更可正确地应用到数据库。

数据库

只有当数据库中不包含任何表时才允许被删除,这能最大程度避免误删除的发生。建议错误等级:错误

    系统

    字符集决定了表中可以存储哪些字符,使用错误的字符集可能导致应用中的某些字符无法正确存储与显示,例如中文与 Emoji 表情。建议错误等级:错误

    • 允许的字符集:
      utf8mb4

    字符序决定了字符比对与排序的规则,例如使用不区分大小写的字符序时 "ABC" 与 "abc" 在查询时将被视为相同字符串。建议错误等级:错误

    • 允许的规则限制:
      utf8mb4_0900_ai_ci

    过长的注释将导致 Schema 易读性降低,并可能带来潜在的性能风险。建议错误等级:警告

    • 注释长度上限: 64

    某些通用列有助于更好的维护应用,例如增加 "ID" 作为业务无关的通用主键避免了业务变化(如业务合并)导致的主键冲突,某些场景还能带来更好的数据插入性能。建议错误等级:警告

    • 必须包含的字段名:
      id created_ts updated_ts creator_id updater_id

    滥用列类型可能对系统可维护性与性能带来严重负面影响,例如使用 "LOB" 类列存放大量音视频数据可能导致数据库性能降低、备份恢复时间延长、数据同步工具不兼容等问题。建议错误等级:错误

    • 禁止的类型:
      JSON

    表中的字段不允许存在 NULL 值。

      修改列类型可能影响系统的性能、可维护性,甚至导致数据丢失。建议错误等级:警告

        会和已经存在的 NULL 数据不兼容,此外旧应用代码中未提供有效值的插入语句都将报错。建议错误等级:错误

          "CHANGE COLUMN" 是 MySQL 特有的语法,可以同时修改列名与其他属性,但可能导致修改属性时误改了列名,建议仍然使用标准的 "RENAME","MODIFY" 语句区分两类变更。建议错误等级:错误

            修改列顺序可能导致某些依赖原表默认顺序的应用或视图出现不符合预期的结果,例如 "SELECT * "。建议错误等级:警告

              MySQL 的自增列一般用做业务无关主键,使用整数类型占用更少的存储空间,还能让主键索引结构更紧凑,带来更好的查询与 DML 性能。建议错误等级:错误

                字符集一般建议在数据库级别或表级别设置,更细粒度的字符集设置极易造成开发管理混乱。建议错误等级:错误

                  无符号类型不存储负数,同样的类型存放的数值范围增加一倍,可以避免自增列超出上限。建议错误等级:警告

                    对列添加注释是良好的开发习惯,但过长的注释将导致 Schema 易读性降低。建议错误等级:警告

                    • 必须注释: true
                    • 长度限制: 64

                    "CHAR" 是定长类型,例如 CHAR(20) 列即便只存放1个字符也将占用20个字符空间造成浪费,当字符串过长且长度不固定时,MySQL 可考虑用 VARCHAR 替代,PostgreSQL 可考虑用 TEXT 替代。建议错误等级:错误

                    • 最大长度: 20

                    结合管理要求限制自增列的初始值。建议错误等级:警告

                    • 初始值: 1

                    列需要调用函数获取系统时间的情况一般只包括记录创建时间的 "DEFAULT NOW()" 与记录更新时间的 "DEFAULT NOW() ON UPDATE NOW()",额外的列记录系统时间没有意义且会增加资源开销。建议错误等级:错误

                      设置符合业务特点的默认值可以有效提升下游统计分析业务的数据质量,此规范不检查 "PRIMARY KEY", "JSON", "BLOB", "TEXT", "GEOMETRY", "AUTO_INCREMENT", "GENERATED" 类型。建议错误等级:警告

                        Schema

                        某些变更可能影响现有应用功能,例如修改数据库对象名,增加新的约束等,此规范可避免不谨慎变更导致现有应用运行失败。建议错误等级:警告

                          主键除了有业务上的价值,在 MySQL 中还对高并发查询有益,同时各种数据同步、比对、回滚的工具往往也要求表有主键。建议错误等级:错误

                            外键的优缺点争议较大,使用外键可能导致数据库变更、扩展(如分库)等工作的难度明显增加,甚至无法使用一些工具。因此可以考虑在应用层实现外键约束。建议错误等级:警告

                              通过重命名待删除表,例如增加 _del 后缀,可以有效避免误操作发生。建议错误等级:错误

                              • 命名规则(正则): _del$

                              在一些数据库引擎中,分区表技术并不成熟,使用与维护都较为不便,因此更倾向于通过分库分表等方式进行人工数据分区。建议错误等级:警告

                                配置表是否需要注释和最大注释长度。

                                • 必须注释: true
                                • 长度限制: 64
                                语句

                                SELECT * 拉取整行数据可能造成不必要的资源开销,同时一旦表增减列,也可能造成应用出现不符合预期的结果。建议错误等级:错误

                                  语句不带过滤条件,查询可能导致巨大的资源开销,DML 更可能导致大规模数据丢失。建议错误等级:错误

                                    当使用左模糊匹配,例如 "LIKE '%ABC'",数据库优化器将无法进行快速索引扫描,而只能执行全表或全索引扫描,可能造成极为严重的性能问题。建议错误等级:错误

                                      某些情况要求多条语句包含在一个事务中由系统提交,只允许同时成功或同时失败,以便部分出错时快速重跑,因此不允许出现显式的 "COMMIT"。建议错误等级:警告

                                        如果 DML 语句中使用 LIMIT 不伴随 ORDER BY,影响的行是不确定的,在某些复制模式下可能导致主库与从库变更了不同的行,造成数据不一致。建议错误等级:错误

                                          排序操作是极为耗费资源的,对于更新与删除操作应该尽可能用确定的过滤条件,而不要使用 ORDER BY 加 LIMIT 的方式。建议错误等级:错误

                                            每一次对表的变更都可能造成锁表并且消耗大量资源,如果存在对同一张表的多次变更,应该合并为一个变更语句。建议错误等级:错误

                                              "INSERT INTO table VALUES (...)" 语句没有显式列出列名,一旦发生列顺序变化或列增减,语句就可能失败或写入不符合预期的数据。建议错误等级:错误

                                                对待插入的数据进行随机排序是没有意义的,只会无端消耗资源。建议错误等级:错误

                                                  通过提示插入的行数辅助判断语句是否符合业务预期。建议错误等级:警告

                                                  • 最大插入行数: 1000

                                                  通过提示更新或删除的行数辅助判断语句是否符合业务预期。建议错误等级:警告

                                                  • 最大影响行数: 1000

                                                  当语法正确但表名错误或权限不足时,可以在正式运行前通过模拟运行发现。建议错误等级:警告

                                                    在 PostgreSQL 11 之前的版本中,添加带有默认值的列将导致全表锁定无法读写,这可能导致业务中断。在 PostgreSQL 11 及以上版本中该问题已得到优化,无需关注此规范。建议错误等级:警告

                                                      在 PostgreSQL 11 之前的版本中,添加 CHECK 约束将对已有数据进行校验并导致全表锁定无法读写,这可能导致业务中断。建议附带 "NOT VALID" 选项只对新数据进行校验,变更完成后再手动校验已有数据。在 PostgreSQL 11 及以上版本中该问题已得到优化,无需关注此规范。建议错误等级:警告

                                                        在 PostgreSQL 11 之前的版本中,向表中添加 NOT NULL 约束将对已有数据进行校验并导致全表锁定无法读写,这可能导致业务中断。在 PostgreSQL 11 及以上版本中该问题已得到优化,无需关注此规范。建议错误等级:警告

                                                          命名

                                                          默认格式为全小写字母,单词之间以下划线分割,长度不超过 63 个字符,例如 "abc","abc_def"。建议错误等级:警告

                                                          • 表命名规则(正则): ^[a-z]+(_[a-z]+)*$
                                                          • 长度限制: 63

                                                          默认格式为全小写字母,单词之间以下划线分割,长度不超过 63 个字符,例如 "abc","abc_def"。建议错误等级:警告

                                                          • 列命名规则(正则): ^[a-z]+(_[a-z]+)*$
                                                          • 长度限制: 63

                                                          允许名字为空并由数据库自动命名,若非空则默认格式为 uk_<表名>_<唯一键包含的列名组合> ,且不超过 63 个字符,例如 "uk_my_table_id_name"。建议错误等级:警告

                                                          • 唯一键命名规则: ^$|^uk_{{table}}_{{column_list}}$
                                                          • 长度限制: 63

                                                          允许名字为空并由数据库自动命名,若非空则默认格式为 pk_<表名>_<主键包含的列名组合> ,且不超过 63 个字符,例如 "pk_my_table_id_name"。建议错误等级:警告

                                                          • 主键命名规则: ^$|^pk_{{table}}_{{column_list}}$
                                                          • 长度限制: 63

                                                          允许名字为空并由数据库自动命名,若非空则默认格式为 idx_<表名>_<索引包含的列名组合> ,且不超过 63 个字符,例如 "idx_my_table_id_name"。建议错误等级:警告

                                                          • 索引命名规则: ^$|^idx_{{table}}_{{column_list}}$
                                                          • 长度限制: 63

                                                          允许名字为空并由数据库自动命名,若非空则默认格式为 fk_<目标表名>_<目标列名>_<被引用表名>_<被引用列名>,且不超过 63 个字符,例如 "fk_my_table_id_foreign_table_id"。

                                                          • 外键命名规则: ^$|^fk_{{referencing_table}}_{{referencing_column}}_{{referenced_table}}_{{referenced_column}}$
                                                          • 长度限制: 63

                                                          默认列名为 "ID",且不超过 63 个字符。

                                                          • 自增列命名规则(正则): ^id$
                                                          • 长度限制: 63
                                                          索引

                                                          创建索引含重复列时语句将执行失败。建议错误等级:错误

                                                            "BLOB" 等类型一般用于存放二进制数据,并不会作为查询条件,如果误在此类列上创建索引,将占用大量资源并产生严重的性能问题。建议错误等级:错误

                                                              限制主键类型必须是 INT 或 BIGINT。

                                                                组合索引列超过 5 个对查询性能的提升并不明显,但却占用大量空间并降低 DML 性能。建议错误等级:警告

                                                                • 字段数量上限: 5

                                                                索引虽然能提升查询性能,但却占用大量空间并降低 DML 性能,因此不建议单个表创建的索引数量超过5个。建议错误等级:警告

                                                                • 索引数量上限: 5

                                                                合适的主键类型可以优化存储结构,减少空间占用并带来更好的插入与查询性能。建议错误等级:警告

                                                                • 允许的主键列的类型:
                                                                  SERIAL BIGSERIAL

                                                                在 PostgreSQL 11 及以上版本中,使用普通方式创建索引将导致表锁定无法写入数据,使用 "CONCURRENTLY" 模式可以实现无锁创建索引,不影响表的正常访问。建议错误等级:警告

                                                                  引擎

                                                                  InnoDB 是 MySQL 默认的存储引擎,能够确保事务一致性,同时对高并发低延迟的场景有更好的性能表现,还可以支持在线数据备份与恢复,是 OLTP 业务的首选。建议错误等级:错误

                                                                    Made by Bytebase at 2023-03-24