关于数据库的DML操作注意事项

前言

  前些天要导入一些车商的初始化数据,发生了一件比较重大的数据错误,后面发现是sql写错了,导致整个数据表被update掉,当然数据量还不是很大,恢复了两个多小时,就把问题解决了。 但是这个事情让我考虑了很久,毕竟入行这么多年,还没有出现过这样的失误。下面就是我要介绍的几点方案,可以避免上述事情发生。

正文

一、首先我觉得框架的持久层对于DML的操作缺乏一定的校验,在安全性上是有问题的。

eg:   update  tb_01 set a =xx,b==xxx where 1=1;

  update  tb_01 set a =xx,b==xxx;

update  tb_01 set a =xx,b==xxx where a and b;

类似于这样的SQL是缺乏校验的。https://my.oschina.net/mingdongcheng/blog/52440,这是在开源中国上面看的解决mybaits中防止批量更新做的拦截器。我们目前用的rose框架,通过查看rose的源代码,在Rose(SystemInterpreter)类中也可以加入相应的校验拦截器,校验拦截器包括以下几点:

(1)update语句中时候存在WHERE关键字,若不存在,则不会更新,并且抛出异常。

(2)update语句中存在WHERE关键字,若存在,则检查是否存在(=,<>,!==)等符号,若存在,则继续,若不存在,是否存在(like、in not in 、exist、not exist)等关键字,当然not in或者not exist可以不包含,若存在,则继续,否则不会更新,并且抛出异常。

这样可以防止批量更新的问题。

二、以前的时候觉得一个update语句其实没有必要有返回值,其实经历了这件事后,我觉得这个是一个比较好的编码行为,如果你更新的数据和你预期的数据不一致,那证明你错了或者你写的SQL错了,这就可以有效的防止这种批量更新的问题产生。

int count=update tb_02 set a=xxx where b=xx;

if(count!=1){

throw new SQLException("您所更新的数据影响0行,请注意查看");

}

上述是伪代码。但是意思是显而易见的。我们预知该SQL只能更新成功一条记录,有其他记录都是错误的。当然上面还有一个解决方案就是可以参照mybaits中校验的案例,设置主键注解,在DML 操作中,这是可以防止批量更新产生的数据问题。

当然有时候我们更新的数据也不是只有一行,有可能是多行,而且是无法预料的。这个时候我们可以使用两种方案进行处理

1)使用触发器的方式进行处理:

在数据库中设置相应DML操作的触发器,每次做DML操作时,查询总数和当前数据影响的总数作比较。

弊端:使用SQL脚本进行批处理时可能会受到影响,DML的性能可能会收影响,但是基本上不是特别大,可以忽略不计。

2)在进行DML操作之前,首先查询总数,然后进行DML操作,然后返回值和总数进行比较

弊端 :性能可能受影响,但是如果是特别重要的数据,我觉得这时候性能问题基本可以忽略不计。

三、其实这也是个人习惯问题,每次的sql写完了以后,需要检查,在开发环境进行测试。这是必要的步骤,但是有时候时间比较急,你可能会忘记这个步骤,觉得一定没问题,上线就是致命的。

四、比较重要的数据,我们可以做一些审计日志,这也是必要的,对于数据的流向和数据恢复等都有迹可循,对于数据恢复有比较大的好处。当然审计日志可以使用异步的并发框架或者消息队列去处理。

五、当然在上线的时候,数据的备份这是很有必要的,上线前需要备份数据库,上线过程中存在修复难度比较大的问题,可以做到数据回退,减少损失。

弊端:数据备份有可能存在数据延迟的现象,如果数据回退的话,有可能存在数据丢失。

总结

  上述提到的解决方案从持久层框架的改进、到程序员基本的一些良好习惯的养成、审计日志、还有数据备份等多个方面防止DML操作中防止批量更新引起的数据问题。DML主要包括(delete,update)操作。

其实对于我们来说,互联网就是玩数据,数据就是一切的根本,也是一切的来源,所以数据的安全性和有效性就显得特别重要。

时间: 2024-08-27 12:50:47

关于数据库的DML操作注意事项的相关文章

MySQL学习笔记——DML操作

有关数据库的DML操作 -insert into -delete.truncate -update -select -条件查询 -查询排序 -聚合函数 -分组查询 多表连接和子查询

php中对MYSQL操作之预处理技术(1)数据库dml操作语句

<?php //预处理技术 //创建一个mysqli对象 $mysqli = new MySQLi("主机名","mysql用户名","密码","数据库名"); //判断是否链接成功 if($mysqli->connect_error){ die($mysqli->connect_error); } //创建预编译对象 $sql = "insert into 表名 (name,qq,age) val

Python数据库操作 DML操作-数据的增删改#学习猿地

# MySQL 数据操作 DML > 数据的DML操作:添加数据,修改数据,删除数据 ## 添加数据 > 格式: insert into 表名[(字段列表)] values(值列表...); ```sql --标准添加(指定所有字段,给定所有的值) mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138'); Query OK, 1 row affected (0.13 sec

使用Trigger审计一张表的DML操作

最近ogg的灾备端复制进程中的一张表老是报错ORA-04031,但是又查不到原因,于是想用审计的方法来看到底这张表是被谁做了DML操作,把数据搞没了.本来想用数据库自带的审计功能参考:http://hbxztc.blog.51cto.com/1587495/1870181 但是需要重启数据库,就放弃了,上网查资料看到有人用触发器来实现这个功能,于是自己也做了尝试. 平台11.2.0.4 [email protected]>select * from v$version; BANNER -----

如何使用Logminer来分析具体的DML操作日志

如何使用Logminer来分析具体的DML操作日志在Oracle数据库维护中,常常需要分析原来数据库都做了哪些删除.更新.增加数据的操作,所以一般需要用到Logminer这工具来分析归档日志.环境:AIX5.3+Oracle10.2.0.1   使用IBM的Tivoli Storage Manager把数据库数据.归档日志备份到带库中 1.确定具体时间的DML操作,把相应的归档日志从带库恢复到数据库中2.用Logminer来分析相应的归档日志 一.在sqlplus用sys超级用户登陆数据库中,然

salesforce零基础学习(七十一)级联表DML操作

曾经做项目没有考虑那么多,对于级联表操作都是正常的一步一步操作,没有考虑过失败情况,最近项目遇见了失败的情况,导致碰到了相应的情况,特此mark一下,免得后期继续踩坑. 需求如下:新建页面,页面中包含1.新建企业,2.新建联系人,3.新建机会.任何一步的逻辑或者DML操作失败都会导致整体的回滚.只有当三步都正常插入成功了以后才会跳转到新生成的机会的标准页面. 1.NewOpportunityController:这里做了一个逻辑判断,当联系人为空情况下,不允许新建联系人.当然,现实场景不会在这里

数据库的CRUD操作

一:数据库的CRUD操作,C是指create新增,R是指retrieve检索,U是指update更改,D是指delete删除 SQL语句分为3类: 1.DDL指数据定义语言如:create,drop,alter等: 2.DML指数据操纵语言:CRUD: 3.DCL指数据控制语言:备份语言之类. 数据库类型分为3大类: 1.关系型数据库:用表存储数据,易于检索,冗余度较小,现在用的就是关系型数据库. 2.层次型数据库,不常见 3.网状型数据库,不常见 二:CRUD操作语法 首先创建一个数据库,一个

Oracle锁2:DML操作和锁

Oracle为DML操作自动获取行锁和表锁,操作的类型决定了锁的行为,下面对DML操作锁的情况作了一个汇总: SQL Statement Row Locks Table Lock Mode RS RX S SRX X SELECT ... FROM table... -- none Y Y Y Y Y INSERT INTO table ... Yes SX Y Y N N N UPDATE table ... Yes SX Y(注) Y(注) N N N MERGE INTO table ..

flashback之——挖掘SCN(DDL和DML操作示例)

------------------------------------------------------------------------------------------- 1.查询当前日志组21:43:00 [email protected]>select * from v$log;          1    1    36   52428800   512     1 NO  CURRENT     1349824 2.查询日志文件 21:42:44 [email protect