rule

package
v1.2205.0-pre1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2022 License: MPL-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RuleTypeGlobalConfig       = "全局配置"
	RuleTypeNamingConvention   = "命名规范"
	RuleTypeIndexingConvention = "索引规范"
	RuleTypeDDLConvention      = "DDL规范"
	RuleTypeDMLConvention      = "DML规范"
	RuleTypeUsageSuggestion    = "使用建议"
	RuleTypeIndexOptimization  = "索引优化"
)

rule type

View Source
const (
	DDLCheckPKWithoutIfNotExists                = "ddl_check_table_without_if_not_exists"
	DDLCheckObjectNameLength                    = "ddl_check_object_name_length"
	DDLCheckObjectNameUsingKeyword              = "ddl_check_object_name_using_keyword"
	DDLCheckPKNotExist                          = "ddl_check_pk_not_exist"
	DDLCheckPKWithoutBigintUnsigned             = "ddl_check_pk_without_bigint_unsigned"
	DDLCheckPKWithoutAutoIncrement              = "ddl_check_pk_without_auto_increment"
	DDLCheckPKProhibitAutoIncrement             = "ddl_check_pk_prohibit_auto_increment"
	DDLCheckColumnCharLength                    = "ddl_check_column_char_length"
	DDLDisableFK                                = "ddl_disable_fk"
	DDLCheckIndexCount                          = "ddl_check_index_count"
	DDLCheckCompositeIndexMax                   = "ddl_check_composite_index_max"
	DDLCheckTableDBEngine                       = "ddl_check_table_db_engine"
	DDLCheckTableCharacterSet                   = "ddl_check_table_character_set"
	DDLCheckIndexedColumnWithBlob               = "ddl_check_index_column_with_blob"
	DDLCheckAlterTableNeedMerge                 = "ddl_check_alter_table_need_merge"
	DDLDisableDropStatement                     = "ddl_disable_drop_statement"
	DDLCheckTableWithoutComment                 = "ddl_check_table_without_comment"
	DDLCheckColumnWithoutComment                = "ddl_check_column_without_comment"
	DDLCheckIndexPrefix                         = "ddl_check_index_prefix"
	DDLCheckUniqueIndexPrefix                   = "ddl_check_unique_index_prefix"
	DDLCheckUniqueIndex                         = "ddl_check_unique_index"
	DDLCheckColumnWithoutDefault                = "ddl_check_column_without_default"
	DDLCheckColumnTimestampWithoutDefault       = "ddl_check_column_timestamp_without_default"
	DDLCheckColumnBlobWithNotNull               = "ddl_check_column_blob_with_not_null"
	DDLCheckColumnBlobDefaultIsNotNull          = "ddl_check_column_blob_default_is_not_null"
	DDLCheckColumnEnumNotice                    = "ddl_check_column_enum_notice"
	DDLCheckColumnSetNotice                     = "ddl_check_column_set_notice"
	DDLCheckColumnBlobNotice                    = "ddl_check_column_blob_notice"
	DDLCheckIndexesExistBeforeCreateConstraints = "ddl_check_indexes_exist_before_creat_constraints"
	DDLCheckDatabaseCollation                   = "ddl_check_collation_database"
	DDLCheckDecimalTypeColumn                   = "ddl_check_decimal_type_column"
	DDLCheckDatabaseSuffix                      = "ddl_check_database_suffix"
	DDLCheckPKName                              = "ddl_check_pk_name"
	DDLCheckTransactionIsolationLevel           = "ddl_check_transaction_isolation_level"
	DDLCheckTablePartition                      = "ddl_check_table_partition"
	DDLCheckIsExistLimitOffset                  = "ddl_check_is_exist_limit_offset"
	DDLCheckIndexOption                         = "ddl_check_index_option"
	DDLCheckObjectNameUseCN                     = "ddl_check_object_name_using_cn"
	DDLCheckCreateView                          = "ddl_check_create_view"
	DDLCheckCreateTrigger                       = "ddl_check_create_trigger"
	DDLCheckCreateFunction                      = "ddl_check_create_function"
	DDLCheckCreateProcedure                     = "ddl_check_create_procedure"
	DDLCheckTableSize                           = "ddl_check_table_size"
	DDLCheckIndexTooMany                        = "ddl_check_index_too_many"
	DDLCheckRedundantIndex                      = "ddl_check_redundant_index"
)

inspector DDL rules

View Source
const (
	DMLCheckWithLimit                    = "dml_check_with_limit"
	DMLCheckWithOrderBy                  = "dml_check_with_order_by"
	DMLCheckWhereIsInvalid               = "all_check_where_is_invalid"
	DMLDisableSelectAllColumn            = "dml_disable_select_all_column"
	DMLCheckInsertColumnsExist           = "dml_check_insert_columns_exist"
	DMLCheckBatchInsertListsMax          = "dml_check_batch_insert_lists_max"
	DMLCheckWhereExistFunc               = "dml_check_where_exist_func"
	DMLCheckWhereExistNot                = "dml_check_where_exist_not"
	DMLCheckWhereExistImplicitConversion = "dml_check_where_exist_implicit_conversion"
	DMLCheckLimitMustExist               = "dml_check_limit_must_exist"
	DMLCheckWhereExistScalarSubquery     = "dml_check_where_exist_scalar_sub_queries"
	DMLWhereExistNull                    = "dml_check_where_exist_null"
	DMLCheckSelectForUpdate              = "dml_check_select_for_update"
	DMLCheckNeedlessFunc                 = "dml_check_needless_func"
	DMLCheckFuzzySearch                  = "dml_check_fuzzy_search"
	DMLCheckNumberOfJoinTables           = "dml_check_number_of_join_tables"
	DMLCheckIfAfterUnionDistinct         = "dml_check_is_after_union_distinct"
	DMLCheckExplainAccessTypeAll         = "dml_check_explain_access_type_all"
	DMLCheckExplainExtraUsingFilesort    = "dml_check_explain_extra_using_filesort"
	DMLCheckExplainExtraUsingTemporary   = "dml_check_explain_extra_using_temporary"
	DMLCheckTableSize                    = "dml_check_table_size"
)

inspector DML rules

View Source
const (
	ConfigDMLRollbackMaxRows       = "dml_rollback_max_rows"
	ConfigDDLOSCMinSize            = "ddl_osc_min_size"
	ConfigDDLGhostMinSize          = "ddl_ghost_min_size"
	ConfigOptimizeIndexEnabled     = "optimize_index_enabled"
	ConfigDMLExplainPreCheckEnable = "dml_enable_explain_pre_check"
)

inspector config code

View Source
const (
	DefaultMultiParamsFirstKeyName  = "multi_params_first_key"
	DefaultMultiParamsSecondKeyName = "multi_params_second_key"
)
View Source
const DefaultSingleParamKeyName = "first_key" // For most of the rules, it is just has one param, this is first params.

Variables

View Source
var (
	RuleHandlerMap = map[string]RuleHandler{}
)
View Source
var RuleHandlers = []RuleHandler{

	{
		Rule: driver.Rule{
			Name: ConfigDMLRollbackMaxRows,
			Desc: "在 DML 语句中预计影响行数超过指定值则不回滚",

			Level:    driver.RuleLevelNotice,
			Category: RuleTypeGlobalConfig,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  "最大影响行数",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},
	{
		Rule: driver.Rule{
			Name: ConfigDDLOSCMinSize,
			Desc: "改表时,表空间超过指定大小(MB)审核时输出osc改写建议",

			Level:    driver.RuleLevelNormal,
			Category: RuleTypeGlobalConfig,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "16",
					Desc:  "表空间大小(MB)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTableSize,
			Desc:     "检查DDL操作的表是否超过指定数据量",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDDLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "16",
					Desc:  "表空间大小(MB)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: "执行DDL的表 %v 空间超过 %vMB",
		Func:    checkDDLTableSize,
	}, {
		Rule: driver.Rule{
			Name:     DDLCheckIndexTooMany,
			Desc:     "检查DDL创建的新索引对应字段是否已存在过多索引",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeIndexingConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "2",
					Desc:  "单字段的索引数最大值",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: "字段 %v 上的索引数量超过%v个",
		Func:    checkIndex,
	},
	{
		Rule: driver.Rule{
			Name:     ConfigDMLExplainPreCheckEnable,
			Desc:     "使用explain加强预检查能力",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeGlobalConfig,
		},
		Func: nil,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckRedundantIndex,
			Desc:     "检查DDL是否创建冗余的索引",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexOptimization,
		},
		Message:      "%v",
		AllowOffline: true,
		Func:         checkIndex,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckTableSize,
			Desc:     "检查DML操作的表是否超过指定数据量",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDMLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "16",
					Desc:  "表空间大小(MB)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: "执行DML的表 %v 空间超过 %vMB",
		Func:    checkDMLTableSize,
	},

	{
		Rule: driver.Rule{
			Name:     ConfigOptimizeIndexEnabled,
			Desc:     "索引创建建议",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeIndexOptimization,
			Params: params.Params{
				&params.Param{
					Key:   DefaultMultiParamsFirstKeyName,
					Value: "1000000",
					Desc:  "计算列基数阈值",
					Type:  params.ParamTypeInt,
				},
				&params.Param{
					Key:   DefaultMultiParamsSecondKeyName,
					Value: "3",
					Desc:  "联合索引最大列数",
					Type:  params.ParamTypeInt,
				},
			},
		},
	},

	{
		Rule: driver.Rule{
			Name: ConfigDDLGhostMinSize,
			Desc: "改表时,表空间超过指定大小(MB)时使用gh-ost上线",

			Level:    driver.RuleLevelNormal,
			Category: RuleTypeGlobalConfig,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "16",
					Desc:  "表空间大小(MB)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},

	{
		Rule: driver.Rule{
			Name:     DDLCheckPKWithoutIfNotExists,
			Desc:     "新建表必须加入if not exists create,保证重复执行不报错",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "新建表必须加入if not exists create,保证重复执行不报错",
		AllowOffline: true,
		Func:         checkIfNotExist,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckObjectNameLength,
			Desc:     "表名、列名、索引名的长度不能大于指定字节",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "64",
					Desc:  "最大长度(字节)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      "表名、列名、索引名的长度不能大于%v字节",
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckPKNotExist,
			Desc:     "表必须有主键",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexingConvention,
		},
		Message:              "表必须有主键",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                 checkPrimaryKey,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckPKWithoutAutoIncrement,
			Desc:     "主键建议使用自增",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexingConvention,
		},
		Message:              "主键建议使用自增",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                 checkPrimaryKey,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckPKWithoutBigintUnsigned,
			Desc:     "主键建议使用 bigint 无符号类型,即 bigint unsigned",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexingConvention,
		},
		Message:              "主键建议使用 bigint 无符号类型,即 bigint unsigned",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                 checkPrimaryKey,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnCharLength,
			Desc:     "char长度大于20时,必须使用varchar类型",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDDLConvention,
		},
		Message:      "char长度大于20时,必须使用varchar类型",
		AllowOffline: true,
		Func:         checkStringType,
	},
	{
		Rule: driver.Rule{
			Name:     DDLDisableFK,
			Desc:     "禁止使用外键",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexingConvention,
		},
		Message:      "禁止使用外键",
		AllowOffline: true,
		Func:         checkForeignKey,
	},
	{
		Rule: driver.Rule{
			Name:  DDLCheckIndexCount,
			Desc:  "索引个数建议不超过阈值",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeIndexingConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "5",
					Desc:  "最大索引个数",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:              "索引个数建议不超过%v个",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                 checkIndex,
	},
	{
		Rule: driver.Rule{
			Name:  DDLCheckCompositeIndexMax,
			Desc:  "复合索引的列数量不建议超过阈值",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeIndexingConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  "最大索引列数量",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:              "复合索引的列数量不建议超过%v个",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                 checkIndex,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckObjectNameUsingKeyword,
			Desc:     "数据库对象命名禁止使用保留字",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,
		},
		Message:      "数据库对象命名禁止使用保留字 %s",
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckObjectNameUseCN,
			Desc:     "数据库对象命名只能使用英文、下划线或数字,首字母必须是英文",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,
		},
		Message:      "数据库对象命名只能使用英文、下划线或数字,首字母必须是英文",
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTableDBEngine,
			Desc:     "必须使用指定数据库引擎",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "Innodb",
					Desc:  "数据库引擎",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "必须使用%v数据库引擎",
		AllowOffline: false,
		Func:         checkEngine,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTableCharacterSet,
			Desc:     "必须使用指定数据库字符集",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4",
					Desc:  "数据库字符集",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "必须使用%v数据库字符集",
		AllowOffline: false,
		Func:         checkCharacterSet,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckIndexedColumnWithBlob,
			Desc:     "禁止将blob类型的列加入索引",
			Level:    driver.RuleLevelError,
			Category: RuleTypeIndexingConvention,
		},
		Message:              "禁止将blob类型的列加入索引",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                 disableAddIndexForColumnsTypeBlob,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWhereIsInvalid,
			Desc:     "禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDMLConvention,
		},
		Message:      "禁止使用没有where条件的sql语句或者使用where 1=1等变相没有条件的sql",
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckAlterTableNeedMerge,
			Desc:     "存在多条对同一个表的修改语句,建议合并成一个ALTER语句",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "已存在对该表的修改语句,建议合并成一个ALTER语句",
		AllowOffline: false,
		Func:         checkMergeAlterTable,
	},
	{
		Rule: driver.Rule{
			Name:     DMLDisableSelectAllColumn,
			Desc:     "不建议使用select *",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "不建议使用select *",
		AllowOffline: true,
		Func:         checkSelectAll,
	},
	{
		Rule: driver.Rule{
			Name:     DDLDisableDropStatement,
			Desc:     "禁止除索引外的drop操作",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "禁止除索引外的drop操作",
		AllowOffline: true,
		Func:         disableDropStmt,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTableWithoutComment,
			Desc:     "表建议添加注释",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "表建议添加注释",
		AllowOffline: true,
		Func:         checkTableWithoutComment,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnWithoutComment,
			Desc:     "列建议添加注释",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "列建议添加注释",
		AllowOffline: true,
		Func:         checkColumnWithoutComment,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckIndexPrefix,
			Desc:     "普通索引必须使用固定前缀",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "idx_",
					Desc:  "索引前缀",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "普通索引必须要以\"%v\"为前缀",
		AllowOffline: true,
		Func:         checkIndexPrefix,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckUniqueIndexPrefix,
			Desc:     "unique索引必须使用固定前缀",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "uniq_",
					Desc:  "索引前缀",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "unique索引必须要以\"%v\"为前缀",
		AllowOffline: true,
		Func:         checkUniqIndexPrefix,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckUniqueIndex,
			Desc:     "unique索引名必须使用 IDX_UK_表名_字段名",
			Level:    driver.RuleLevelError,
			Category: RuleTypeNamingConvention,
		},
		Message:      "unique索引名必须使用 IDX_UK_表名_字段名",
		AllowOffline: true,
		Func:         checkUniqIndex,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnWithoutDefault,
			Desc:     "除了自增列及大字段列之外,每个列都必须添加默认值",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDDLConvention,
		},
		Message:      "除了自增列及大字段列之外,每个列都必须添加默认值",
		AllowOffline: true,
		Func:         checkColumnWithoutDefault,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnTimestampWithoutDefault,
			Desc:     "timestamp 类型的列必须添加默认值",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDDLConvention,
		},
		Message:      "timestamp 类型的列必须添加默认值",
		AllowOffline: true,
		Func:         checkColumnTimestampWithoutDefault,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnBlobWithNotNull,
			Desc:     "BLOB 和 TEXT 类型的字段不建议设置为 NOT NULL",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDDLConvention,
		},
		Message:      "BLOB 和 TEXT 类型的字段不建议设置为 NOT NULL",
		AllowOffline: true,
		Func:         checkColumnBlobNotNull,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnBlobDefaultIsNotNull,
			Desc:     "BLOB 和 TEXT 类型的字段不可指定非 NULL 的默认值",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDDLConvention,
		},
		Message:      "BLOB 和 TEXT 类型的字段不可指定非 NULL 的默认值",
		AllowOffline: true,
		Func:         checkColumnBlobDefaultNull,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWithLimit,
			Desc:     "delete/update 语句不能有limit条件",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDMLConvention,
		},
		Message:      "delete/update 语句不能有limit条件",
		AllowOffline: true,
		Func:         checkDMLWithLimit,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWithOrderBy,
			Desc:     "delete/update 语句不能有order by",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDMLConvention,
		},
		Message:      "delete/update 语句不能有order by",
		AllowOffline: true,
		Func:         checkDMLWithOrderBy,
	},
	{

		Rule: driver.Rule{
			Name:     DMLCheckInsertColumnsExist,
			Desc:     "insert 语句必须指定column",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "insert 语句必须指定column",
		AllowOffline: true,
		Func:         checkDMLWithInsertColumnExist,
	},
	{
		Rule: driver.Rule{
			Name:  DMLCheckBatchInsertListsMax,
			Desc:  "单条insert语句,建议批量插入不超过阈值",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeDMLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "5000",
					Desc:  "最大插入行数",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      "单条insert语句,建议批量插入不超过%v条",
		AllowOffline: true,
		Func:         checkDMLWithBatchInsertMaxLimits,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckPKProhibitAutoIncrement,
			Desc:     "主键禁止使用自增",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeIndexingConvention,
		},
		Message:              "主键禁止使用自增",
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                 checkPrimaryKey,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWhereExistFunc,
			Desc:     "避免对条件字段使用函数操作",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "避免对条件字段使用函数操作",
		AllowOffline: false,
		Func:         checkWhereExistFunc,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWhereExistNot,
			Desc:     "不建议对条件字段使用负向查询",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "不建议对条件字段使用负向查询",
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: driver.Rule{
			Name:     DMLWhereExistNull,
			Desc:     "不建议对条件字段使用 NULL 值判断",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "不建议对条件字段使用 NULL 值判断",
		Func:         checkWhereExistNull,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWhereExistImplicitConversion,
			Desc:     "条件字段存在数值和字符的隐式转换",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message: "条件字段存在数值和字符的隐式转换",
		Func:    checkWhereColumnImplicitConversion,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckLimitMustExist,
			Desc:     "delete/update 语句必须有limit条件",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDMLConvention,
		},
		Message:      "delete/update 语句必须有limit条件",
		Func:         checkDMLLimitExist,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckWhereExistScalarSubquery,
			Desc:     "避免使用标量子查询",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "避免使用标量子查询",
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckIndexesExistBeforeCreateConstraints,
			Desc:     "建议创建约束前,先行创建索引",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeIndexingConvention,
		},
		Message: "建议创建约束前,先行创建索引",
		Func:    checkIndexesExistBeforeCreatConstraints,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckSelectForUpdate,
			Desc:     "建议避免使用select for update",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "建议避免使用select for update",
		Func:         checkDMLSelectForUpdate,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:  DDLCheckDatabaseCollation,
			Desc:  "建议使用规定的数据库排序规则",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeDDLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4_0900_ai_ci",
					Desc:  "数据库排序规则",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: "建议使用规定的数据库排序规则为%s",
		Func:    checkCollationDatabase,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckDecimalTypeColumn,
			Desc:     "精确浮点数建议使用DECIMAL",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "精确浮点数建议使用DECIMAL",
		Func:         checkDecimalTypeColumn,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:  DMLCheckNeedlessFunc,
			Desc:  "避免使用不必要的内置函数",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeDMLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "sha(),sqrt(),md5()",
					Desc:  "指定的函数集合(逗号分割)",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "避免使用不必要的内置函数[%v]",
		Func:         checkNeedlessFunc,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckDatabaseSuffix,
			Desc:     "数据库名称必须使用固定后缀结尾",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeNamingConvention,

			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "_DB",
					Desc:  "数据库名称后缀",
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      "数据库名称必须以\"%v\"结尾",
		Func:         checkDatabaseSuffix,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckPKName,
			Desc:     "建议主键命名为\"PK_表名\"",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeNamingConvention,
		},
		Message:      "建议主键命名为\"PK_表名\"",
		Func:         checkPKIndexName,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTransactionIsolationLevel,
			Desc:     "事物隔离级别建议设置成RC",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "事物隔离级别建议设置成RC",
		Func:         checkTransactionIsolationLevel,
		AllowOffline: true,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckFuzzySearch,
			Desc:     "禁止使用全模糊搜索或左模糊搜索",
			Level:    driver.RuleLevelError,
			Category: RuleTypeDMLConvention,
		},
		Message:      "禁止使用全模糊搜索或左模糊搜索",
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckTablePartition,
			Desc:     "不建议使用分区表相关功能",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "不建议使用分区表相关功能",
		AllowOffline: true,
		Func:         checkTablePartition,
	},
	{
		Rule: driver.Rule{
			Name:  DMLCheckNumberOfJoinTables,
			Desc:  "使用JOIN连接表查询建议不超过阈值",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeDMLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  "最大连接表个数",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      "使用JOIN连接表查询建议不超过%v张",
		AllowOffline: true,
		Func:         checkNumberOfJoinTables,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckIfAfterUnionDistinct,
			Desc:     "建议使用UNION ALL,替代UNION",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "建议使用UNION ALL,替代UNION",
		AllowOffline: true,
		Func:         checkIsAfterUnionDistinct,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckIsExistLimitOffset,
			Desc:     "使用LIMIT分页时,避免使用LIMIT M,N",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDMLConvention,
		},
		Message:      "使用LIMIT分页时,避免使用LIMIT M,N",
		AllowOffline: true,
		Func:         checkIsExistLimitOffset,
	},
	{
		Rule: driver.Rule{
			Name:  DDLCheckIndexOption,
			Desc:  "建议选择可选性超过阈值字段作为索引",
			Level: driver.RuleLevelNotice,

			Category: RuleTypeIndexOptimization,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "70",
					Desc:  "可选择性(百分比)",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      "索引 %v 未超过可选性阈值 百分之%v, 不建议选为索引",
		AllowOffline: false,
		Func:         checkIndexOption,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnEnumNotice,
			Desc:     "不建议使用 ENUM 类型",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "不建议使用 ENUM 类型",
		AllowOffline: true,
		Func:         checkColumnEnumNotice,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnSetNotice,
			Desc:     "不建议使用 SET 类型",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "不建议使用 SET 类型",
		AllowOffline: true,
		Func:         checkColumnSetNotice,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckColumnBlobNotice,
			Desc:     "不建议使用 BLOB 或 TEXT 类型",
			Level:    driver.RuleLevelNotice,
			Category: RuleTypeDDLConvention,
		},
		Message:      "不建议使用 BLOB 或 TEXT 类型",
		AllowOffline: true,
		Func:         checkColumnBlobNotice,
	},
	{
		Rule: driver.Rule{
			Name: DMLCheckExplainAccessTypeAll,

			Desc:     "查询的扫描不建议超过指定行数(默认值:10000)",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDMLConvention,
			Params: params.Params{
				&params.Param{
					Key:   DefaultSingleParamKeyName,
					Value: "10000",
					Desc:  "最大扫描行数",
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      "该查询的扫描行数为%v",
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckExplainExtraUsingFilesort,
			Desc:     "该查询使用了文件排序",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDMLConvention,
		},
		Message:      "该查询使用了文件排序",
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: driver.Rule{
			Name:     DMLCheckExplainExtraUsingTemporary,
			Desc:     "该查询使用了临时表",
			Level:    driver.RuleLevelWarn,
			Category: RuleTypeDMLConvention,
		},
		Message:      "该查询使用了临时表",
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckCreateView,
			Desc:     "禁止使用视图",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "禁止使用视图",
		AllowOffline: true,
		Func:         checkCreateView,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckCreateTrigger,
			Desc:     "禁止使用触发器",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "禁止使用触发器",
		AllowOffline: true,
		Func:         checkCreateTrigger,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckCreateFunction,
			Desc:     "禁止使用自定义函数",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "禁止使用自定义函数",
		AllowOffline: true,
		Func:         checkCreateFunction,
	},
	{
		Rule: driver.Rule{
			Name:     DDLCheckCreateProcedure,
			Desc:     "禁止使用存储过程",
			Level:    driver.RuleLevelError,
			Category: RuleTypeUsageSuggestion,
		},
		Message:      "禁止使用存储过程",
		AllowOffline: true,
		Func:         checkCreateProcedure,
	},
}

Functions

This section is empty.

Types

type RuleHandler

type RuleHandler struct {
	Rule                 driver.Rule
	Message              string
	Func                 func(*session.Context, driver.Rule, *driver.AuditResult, ast.Node) error
	AllowOffline         bool
	NotAllowOfflineStmts []ast.Node
}

func (*RuleHandler) IsAllowOfflineRule

func (rh *RuleHandler) IsAllowOfflineRule(node ast.Node) bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL