#Inception 审核规范及原则 ##写在前面的话
MySQL语句的审核,在业界都已经基本被认同了,实际上也是对MySQL语句写法的统一化,标准化,而之前的人工审核,针对标准这个问题其实是很吃力的,标准越多,DBA越累,开发也越累。那么Inception出现之后,它是不怕标准多的,只要DBA定义了为了更好的管理数据库的规则时,Inception就可以很好的执行,并且返回审核结果,那么这一章主要介绍当前Inception在审核时,是使用什么样的规则来做的,并且哪些规则是可以配置的,哪些规则是不可以配置的,这样针对不同的部门或者公司,可以定制不同的规则,而配置参数将在<<Inception所支持的参数变量>>中详细介绍。
下面就是有关审核规范的具体信息,但一些人为的或者逻辑的东西机器没办法搞定的,需要我们DBA自己定义,所有制定的规则,都是以语法正确为前提的,当然首先审核的就是语法问题,如果语法不通过,则整个语句块中,语法出问题的位置前面的语句审核完成,后面则不能将各个语句分开,报错时后面就被认为是一个语句。
重要声明:下面所列出来的规则,不一定能覆盖所有Inception当前已经实现的功能,具体包括什么规则,还需要在使用过程中总结,发现,同时可以结合配置参数来详细了解这些规则。
##支持的语句类型
- use db:此时会检查这个库是不是存在,需要连接到线上服务器来判断。
- set option:现在只需要支持set names charset,设置其它变量时都报错不支持。
- 创建数据库语句
- 插入语句(包括多值插入)
- 查询插入语句
- 删除语句(包括多表删除)
- 更新语句(包括多表更新)
- 创建表语句
- 删除表语句
- 修改表语句
- Truncate表语句
- inception命令集语句(包括管理命令)
##插入语句检查项
- 表是否存在
- 必须指定插入列表,也就是要对哪几个列指定插入值,如insert into t (id,id2) values(...),(可配置)
- 必须指定值列表,与上面对应的列,插入的值是什么,必须要指定。
- 插入列列表与值列表个数相同,上面二者的个数需要相同,如果没有指定列列表(因为可配置),则值列表长度要与表列数相同。
- 不为null的列,如果插入的值是null,报错(可配置)
- 插入指定的列名对应的列必须是存在的。
- 插入指定的列列表中,同一个列不能出现多次。
- 插入值列表中的简单表达式会做检查,但具体包括什么不一一指定
##更新、删除语句检查项
- 表是否存在
- 必须有where条件(可配置)
- delete语句不能有limit条件(可配置)
- 不能有order by语句(可配置)
- 影响行数大于10000条,则报警(数目可配置)
- 对WHERE条件这个表达式做简单检查,具体包括什么不一一指定
- 对更新列的值列表表达式做简单检查,具体不一一指定
- 对更新列对象做简单检查,主要检查列是不是存在等
- 多表更新、删除时,每个表必须要存在
##建表语句检查项 ###表属性的检查项
- 这个表不存在
- 对于create table like,会检查like的老表是不是存在。
- 对于create table db.table,会检查db这个数据库是不是存在
- 表名、列名、索引名的长度不大于64个字节
- 如果建立的是临时表,则必须要以tmp为前缀
- 必须要指定建立innodb的存储引擎(可配置)
- 必须要指定utf8的字符集(字符串可配置,指定支持哪些字符集)
- 表必须要有注释(可配置)
- 表不能建立为分区表(可配置)
- 只能有一个自增列
- 索引名字不能是Primay
- 不支持Foreign key(可配置)
- 建表时,如果指定auto_increment的值不为1,报错(可配置)
- 如果自增列的名字不为id,说明有可能是有意义的,MySQL这样使用比较危险,所以报警(可配置)
###列属性的检查项 - 不能设置列的字符集(可配置)
- 列的类型不能使用集合、枚举、位图类型。(可配置)
- 列必须要有注释(可配置)
- char长度大于20的时候需要改为varchar(长度可配置)
- 列的类型不能是BLOB/TEXT。(可配置)
- 每个列都使用not null(可配置)
- 如果列为BLOB/TEXT类型的,则这个列不能设置为NOT NULL。
- 如何是自增列,则使用无符号类型(可配置)
- 如果自增列,则长度必须要大于等于4个字节(可配置)
- 如果是timestamp类型的,则要必须指定默认值。
- 对于MySQL5.5版本(包含)以下的数据库,不能同时有两个TIMESTAMP类型的列,如果是DATETIME类型,则不能定义成DATETIME DEFAULT CURRENT_TIMESTAMP及ON UPDATE CURRENT_TIMESTAMP等语句。
- 每个列都需要定义默认值,除了自增列、主键列及大字段列之外(可配置)
- 不能有重复的列名
###索引属性检查项 - 索引必须要有名字
- 不能有外键(可配置)
- Unique索引必须要以uniq_为前缀(可配置)
- 普通索引必须要以idx_为前缀(可配置)
- 索引的列数不能超过5个(数目可以配置)
- 表必须要有一个主键(可配置)
- 最多有5个索引(数目可配置)
- 建索引时,指定的列必须存在。
- 索引中的列,不能重复
- BLOB列不能建做KEY
- 索引长度不能超过766
- 不能有重复的索引,名字及内容
###默认值检查项 - BLOB/TEXT类型的列,不能有非NULL的默认值
- MySQL5.5以下(含)的版本,对于DATETIME类型的列,不能有函数NOW()的默认值。
- 如果设置默认值为函数,则只能是NOW()。
- 如果默认值为NULL,但列类型为NOT NULL,或者是主键列,或者定义为自增列,则报错。
- 自增列不能设置默认值。
##修改表语句检查项
- 表是不是存在
###创建索引检查项 - 同上面创建表中的索引检查项 ###加列检查项
- 同上面创建表中的列检查项 ###修改表检查项
- 表是不是存在
- 如果语句块中存在多条对同一个表的修改语句,则建议合并成一个ALTER语句
- 列是否存在
- 剩下的同上面创建表,创建索引,创建列,默认值等检查项一样 ###删除索引检查项
- 表是不是存在
- 检查索引是不是存在
###修改列的默认值检查项 - 同默认值检查项 ###修改表属性
- 表属性只支持对存储引擎、表注释、自增值及默认字符集的修改操作。
- 修改存储引擎时检查是不是Innodb(可配置)。
- 字符集修改检查是不是属于设置参数的值(支持字符集可配置)。 ###转换表字符集
- 字符集修改检查是不是属于设置参数的值(支持字符集可配置)。
#声明
- 针对线上MySQL服务器是不是5.6以上(包含)版本,有不同的处理策略,比如在预估影响行数时,5.6可以直接对任何DML语句做EXPLAIN操作,而在5.5版本中,只支持对SELECT语句执行EXPLAIN操作,而在5.5版本中,有些DML语句是不容易直接转换为SELECT语句去做EXPLAIN,这样导致预估行数为0。
- 还是针对5.6以上版本与5.5版本的不同,DATETIME、TIMESTAMP系列类型在执行时,5.5的限制比较多,而5.6基本通用,所以这上面的处理可能在5.6及5.5版本上,相同语句返回的结果集是不同的(规则是在5.5中以在执行时报的错误信息为准),这与线上版本有关系。