为了方便高效的完成SQL审核任务,我尝试了一次淘宝开源的SQLautoReview。

项目地址:https://github.com/taobao/sqlautoreview
简单概括下其功能:
1、 解析sqlmapfile,利用dom4j从xml文件解析SQL语句,并插入数据库中
2、 分析SQL语句,创建该语句索引脚本
3、 对新的索引与“线上索引”进行合并,生成最终更新脚本
该工具的难点:
1、 对SQL语句的解析,尤其很复杂的sql
2、 SQL语句的提取,基本上规律性是不是很大,索引的建立规则,索引的合并这些是值得大家关注的
整体结构图:

建立索引规则:

1、 如果where等值查询字段中,是primary key的第一个字段,使用主键索引

2、 如果where等值查询字段中,是unique key的第一个字段,使用唯一键索引

3、如果前两个条件不满足,则需要对所有条件字段分成三类,一类是等值操作字段,第二类是非等值操作字段,第三类是排序字段.对于前两类字段,会在这两类columns分别进行Cardinality排序,Cardinality越大,越有可能排在索引字段顺序的最前面.索引字段的组合顺序(等值条件操作字段,排序操作字段,非等值条件操作字段)
4、 如果SQL含有排序字段,会对排序字段的类型,及长度进行检查,如果排序字段中有一个column的type是varchar类型,并且定义的长度超过200,会出现一个Warnning
5、 所生成的创建索引的脚本是最优的.但局部最优,并不代表着全局最优.
合并索引的规则:

1、所有新建索引进行最简单的去重

2、新建索引的索引字段是否是已存在的索引字段的子集,并且索引字段顺序相同.比如一个新建的索引为ind_test_user(user,status),而原来表上存在一个索引ind_test_user(user,status,type),那么这个新建的索引就不需要建了,直接重用原来的索引

3、新建索引的内部也进行2的方式合并

4、以新建索引为标准,如果老的索引是新建索引的子集,老的索引会删除,然后创建一个新的索引

存在缺陷:
1、 对于sqlmapfile的解析仍可能出错,精准度不够
2、 只支持MySQL
3、 对于SQL类型,不支持子查询,以及外连接。
这套开源系统对于采用Java程序非常合适。那对于非Java应用呢?经过@丹臣 大神的指导,对于非Java应用。只需跳过第一步即可。
大致简单介绍下:

自己的环境: linux, jdk1.6,配置java_home, path 变量。

解压程序包,创建log地址,修改配置变量。(具体请参考文档)
productdb.xml 主要指示“线上”数据库的连接:
如:
<?xml version="1.0" encoding="UTF-8"?>
<database><ip>127.0.0.1</ip> <port>3306</port><dbname>dragon</dbname>    <user>root</user>    <password>xxxxxxx</password>
</database>
sqlmapfile.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<sqlmapfile>
<file_id>100</file_id><file_name>/opt/abc.xml</file_name>
</sqlmapfile>

(对于Java应用这个就如何填好,对于非Java应用。这个可以随便写,但是file_id必须和数据库中xmltosql 中的sqlmapfile_id 相对应)

sqlreviewdb.xml 文件指示操作结果
<?xml version="1.0" encoding="UTF-8"?>
<database><ip>127.0.0.1</ip><port>3306</port><dbname>sqlreviewdb</dbname><user>root</user><password>xxxxx</password>
</database>
在sqlreviewdb中创建的表:
  CREATE TABLE `xmltosql` (`id` int(11) NOT NULL AUTO_INCREMENT,`sqlmap_file_id` int(11) NOT NULL,`java_class_id` varchar(200) NOT NULL,`sql_xml` varchar(4000) NOT NULL,`sql_comment` varchar(200) DEFAULT NULL,`real_sql` varchar(4000) NOT NULL,`real_sql_hash` varchar(32) DEFAULT NULL,`table_name` varchar(100) DEFAULT NULL,`status` int(11) DEFAULT NULL,`auto_review_err` varchar(200) DEFAULT NULL,`auto_review_tip` varchar(200) DEFAULT NULL,`auto_review_time` datetime DEFAULT NULL,`sql_auto_index` varchar(200) DEFAULT NULL,`dba_review_time` datetime DEFAULT NULL,`sql_dba_index` varchar(200) DEFAULT NULL,`dba_advice` varchar(200) DEFAULT NULL,`gmt_create` datetime NOT NULL,`gmt_modified` datetime NOT NULL,PRIMARY KEY (`id`),KEY `idx_java_class_id` (`java_class_id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbkCREATE TABLE `mergeresult` (`id` int(11) NOT NULL AUTO_INCREMENT,`sqlmap_file_id` int(11) NOT NULL,`tablename` varchar(30) DEFAULT NULL,`real_tablename` varchar(30) DEFAULT NULL,`exist_indexes` varchar(4000) DEFAULT NULL,`new_indexes` varchar(4000) DEFAULT NULL,`merge_result` varchar(4000) DEFAULT NULL,`gmt_create` datetime NOT NULL,`gmt_modified` datetime NOT NULL,PRIMARY KEY (`id`),KEY `idx_result_sqlmap_file_id` (`sqlmap_file_id`)) ENGINE=InnoDB DEFAULT CHARSET=gbk
配置好后:

第一步:./start_xmltosql.sh 解析sql 并插入到 xmltosql表中。 对于非Java应用来说,我们需要手动将SQL语句插入到表中,注意事项:sqlmap_file_id 这个必须和 sqlmap_file.xml中记录的filed-id 一致。Real_sql 可以是:select id from tasks where task_type= ?,还有status 必须是0 ,其他的可以随便写。

第二步:执行创建索引的脚本,这个会读取sqlreviewdb中待审核的SQL语句,解析SQL,根据规则生成创建索引的脚本,并保存到sqlreviewdb中,整个审核结束。
./start_createindex.sh
第三步是执行索引merge的脚本;
./start_mergeindex.sh

这个会读取sqlreviewdb中的生成的索引,以及这次审核所涉及的表上原有的索引,应用一些规则,进行索引的自动合并,将结果保存在mergeresult 表中的 merge_result 字段,我们在想把办法把这些 结果 应用到线上!

执行结果:
# sh start_createindex.sh
2012-09-26 16:31:14,886 INFO sqlautoreview.CreateIndex - ??????SQL_ID=1,??SQL TEXT?:select id from tasks where task_type= ?2012-09-26 16:31:14,891 INFO sqlautoreview.ParseSQL - SQL at parsing:select id from tasks where task_type= ?2012-09-26 16:31:14,891 DEBUG sqlautoreview.ParseSQL - addToColumnHashMap select_exprs:id2012-09-26 16:31:14,891 DEBUG sqlautoreview.ParseSQL - dealSingleSelectExpr select_expr:id2012-09-26 16:31:14,891 DEBUG sqlautoreview.ParseSQL - column_name:id alias_column_name:id2012-09-26 16:31:14,891 DEBUG sqlautoreview.ParseSQL - column_name: alias_column_name:id
2012-09-26 16:31:14,891 INFO sqlautoreview.ParseSQL - select columns:id
2012-09-26 16:31:14,891 INFO sqlautoreview.ParseSQL - table name:tasks
2012-09-26 16:31:14,892 INFO sqlautoreview.ParseSQL - where condition:task_type= ?2012-09-26 16:31:14,902 DEBUG sqlautoreview.MySQLMetaData - select count(distinct(id)),count(distinct(name)),count(distinct(task_type)),count(distinct(description)),count(distinct(guide_description)),count(distinct(triger_task_ids)),count(distinct(award_gold_money)),count(distinct(award_exp)),count(distinct(start_task_time)),count(distinct(end_task_time)),count(distinct(status)) from (select id,name,task_type,description,guide_description,triger_task_ids,award_gold_money,award_exp,start_task_time,end_task_time,status from tasks limit 10000) aa;2012-09-26 16:31:14,911 INFO sqlautoreview.CreateIndex - create index script: create index idx_tasks_task_type on tasks(task_type);
# sh start_mergeindex.sh
2012-09-26 16:36:45,725 DEBUG sqlautoreview.MySQLMetaData - tasks:PRIMARY(id);id(id,status);id_2(id,task_type);2012-09-26 16:36:45,726 DEBUG sqlautoreview.MergeIndex - 12012-09-26 16:36:45,726 DEBUG sqlautoreview.MergeIndex - tasks2012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,729 DEBUG sqlautoreview.TableMergeIndex - removeExistIndexColumns:12012-09-26 16:36:45,730 DEBUG sqlautoreview.TableMergeIndex - mergeExistIndexes : drop exist index:drop index PRIMARY on tasks2012-09-26 16:36:45,731 DEBUG sqlautoreview.HandleSQLReviewDB - mergeresult sqlmap_file_id -10000000 is deleted.2012-09-26 16:36:45,731 DEBUG sqlautoreview.HandleSQLReviewDB - insert into mergeresult(sqlmap_file_id,tablename,real_tablename,exist_indexes,new_indexes,merge_result,gmt_create,gmt_modified) values(-1000000,'tasks','tasks','PRIMARY(id);id(id,status);id_2(id,task_type);','create index idx_tasks_task_type on tasks(task_type)','create index idx_tasks_task_type on tasks(task_type);drop index PRIMARY on tasks',now(),now())2012-09-26 16:36:45,731 INFO sqlautoreview.MergeIndex - ---------------------------------------------------2012-09-26 16:36:45,731 INFO sqlautoreview.MergeIndex - Table tasks Merge index information as follows:2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - ---------------------------------------------------2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - Exist indexes as follows:
2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - PRIMARY(id)
2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - id(id,status)
2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - id_2(id,task_type)
2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - New indexes as follows:2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - create index idx_tasks_task_type on tasks(task_type)2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - Result indexes as follows:2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - create index idx_tasks_task_type on tasks(task_type)2012-09-26 16:36:45,732 INFO sqlautoreview.MergeIndex - drop index PRIMARY on tasks

转载于:https://blog.51cto.com/weipengfei/1008468

SQL 审核系统体验相关推荐

  1. SQL 审核到底审了个什么 ? 三种角度三种格局

    最近在搞SQL 审核的工作,从开始到目前有3个月的时间, 随着时间的推移从想法很简单认为这个事情很简单,到目前 的认知,还是希望能分享一下. 首先SQL审核到底是从技术入手,还是从规范入手,甚至从 管 ...

  2. SQL审核 | SQLE-SQL审核平台体验报告

    作者:刘新旺 MySQL DBA,专注于 MySQL 数据库多年,现就职一家本地生活服务类互联网公司,负责数据库相关工作. 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载 ...

  3. Linux系统之部署Yearning SQL审核平台

    这里写目录标题 一.Yearning介绍 1.1 Yearning简介 1.2 Yearning特点 1.3 Yearning功能 二.本地环境介绍 2.1 本地环境规划 2.2 本次实践介绍 三.检 ...

  4. 【云和恩墨大讲堂】SQL 审核 | 细致入微,方显价值

    怀晓明 云和恩墨性能优化专家 本文来自于本周四云和恩墨大讲堂怀晓明老师的分享. 内容:作为 DevOps 的最佳落地方式之一的 SQL 审核,如何才能做好?这是一件很有挑战性的事情,他将通过两个具体案 ...

  5. 车金融|GPS审核系统的前世今生

    GPS审核系统历经前后几次自主创新重构以及在需求迭代中小规模重构优化,系统最终能持续半年需求不再迭代,这背后多少有重构带来的变化和影响.GPS审核系统并非最初就有,它仅仅只是原先一个庞大既臃肿系统中的 ...

  6. sql 修改时间戳语句_从 0 到 1 搭建技术中台之 SQL 审核平台

    背景 随着伴鱼业务的快速发展,公司各产品线的业务不断丰富,日常的 SQL 上线也在不断增加.SQL 审核与执行,作为 DBA 每天工作中相当重要的一环,如何保证 SQL 语句的质量,对于系统的高效运行 ...

  7. 应用事件探查器优化SQL Server系统[转]

    应用事件探查器优化SQL Server系统 关键词:Mssql,,概述 当你的SQL Server数据库系统运行缓慢的时候,你或许多多少少知道可以使用SQL Server Profiler(中文叫SQ ...

  8. SQL 审核:基于PG数据库插件hook的SQL规范审核工具

    关注"数据和云",精彩不容错过 内容来源:2017 年 10 月 21 日,平安科技数据库架构师陈刚在"PostgreSQL 2017中国技术大会"进行< ...

  9. videojs默认显示controls 按钮功能失效_一文看懂Yearning SQL审核平台功能模块设计...

    概述 Yearning SQL审核平台目前兼容99%的Mysql 标准SQL语法. 已知不支持的语句类型有: 复杂的查询语句(多表,多函数,非必现.并不是所有复杂语句不支持) create table ...

最新文章

  1. php instr函数,oracle的instr函数用法
  2. 关于Java的Classpath详解
  3. glVertexPointer
  4. PLSQL DEVELOPER 使用技巧
  5. 使用Spring Redis发布/订阅
  6. 【51Nod - 1268】和为K的组合 (背包 或 dfs)
  7. 亲身经历之微信支付沙箱环境扫码支付遇到的那些坑
  8. html快捷键_Mac进阶:掌握这 5 个冷门快捷键,让Mac更好用
  9. 对一个三角形三边如何设计测试用例等价类经典应用
  10. kafka 脚本发送_Apache-Flink深度解析-DataStream-Connectors之Kafka
  11. url解码java_JAVA对URL的解码【转】
  12. 基于阿里云的移动客户端服务器架构图
  13. 单片机输出脉冲的C语言简易程序,单片机简易程序, 电子琴 内附图 有说明...
  14. Python教学视频(五)顺序结构练习
  15. 机器人时代已来!推荐几本机器人学硬核好书
  16. 个股和股票池的beta系数的估算
  17. Pascal VOCdata数据集读取(pytorch)
  18. ACE反应器框架简介
  19. 【Machine Learning】【Andrew Ng】- Quiz2(Week 9)
  20. 【荣耀】2021年招聘开启,新荣耀,新征程 (base Xian or Beijing) - 内推

热门文章

  1. 2015 多校赛 第三场 1002 (hdu 5317)
  2. 近期会将视频在线课堂移植ios,欢迎大家关注
  3. Direct2D教程(五)复合图形
  4. 第几天? 2005
  5. 还是觉得应该动手写点东西....
  6. Asp.net 2.0生命周期
  7. 小熊的人生回忆(五)
  8. 诗与远方:无题(二十六)- 曾经给一个妹子写的一首诗
  9. Python学习笔记之if语句(三)
  10. cookie与session详解、url地址重写