文章转载自「开发者圆桌」一个关于开发者入门、进阶、踩坑的微信公众号

许多OLTP应用的开发者都知道,一些重要的操作要记录操作历史,把操作前的数据备份到历史表,然后再执行相应的修改操作。这样可以获取某个时点的操作日志和操作前的记录值。

要记录操作历史有两个层面,一个是应用层即通过应用程序逻辑实现历史记录的保存,一个是数据库层即数据库归档、审计等DBA管理的功能。这里仅讨论前者。

比如有一个用户表t_user包含id,name,sex,age字段,因为t_user表的修改非常重要,要记录操作历史,一般的做法是建立和t_user结构相同的一个历史表命名为t_user_his,它包含id,name,sex,age字段,同时添加对应的his_id,oper_time,oper_remark等记录操作说明的字段。

OK,表设计完毕了,我们需要在修改时记录用户之前的信息,一般的做法是先来个insert插入历史表,然后再去修改原表数据,把这两个操作放到同一个事务中去处理,释义代码如下:

setAutoCommit(false);

insert into t_user_his(id,name,sex,age,his_id,oper_time,oper_remark) select id,name,sex,age,'历史表id',timestamp,'修改姓名' from t_user where id=18970;

update t_user set name='xxx' where id=18970;

commit();

部署上线一切运行正常,领导非常满意,突然有一天需要在t_user中添加一个phone字段来记录用户的电话号码,软件产品唯一不变的就是下面这个词

没办法只能修改了,需要按照下面几个步骤修改:

首先,修改t_user表添加一个phone字段。

其次,修改t_user_his表添加一个phone字段。

第三,修改涉及到的记录操作历史的SQL,如果有多处也需要一并修改:

setAutoCommit(false);

insert into t_user_his(id,name,sex,age,phone,his_id,oper_time,oper_remark) select id,name,sex,age,phone,'历史表id',timestamp,'修改姓名' from t_user where id=18970;

update t_user set name='xxx' where id=18970;

commit();

最后,编译程序,测试,提交,部署上线,一个流程下来可能要好多天。

问题来了,只能这样处理吗?如何规避字段修改带来的重复修改呢?有没有更好的解决方案呢?答案是肯定的,只需要通过一个简单的修改就可以做到。

我们可以这样来设计t_user_his表的字段,把历史操作相关字段前置,后续字段保持与t_user完全一致,例如t_user_his字段可以这样安排:his_id,oper_time,oper_remark,id,name,sex,age。

应用程序修改如下:

setAutoCommit(false);

insert into t_user_his select ,'历史表id',timestamp,'修改姓名' ,a.* from t_user a  where id=18970;

update t_user set name='xxx' where id=18970;

commit();

这样的话,要添加一个新的phone字段,该如何操作呢?

首先,修改t_user表添加一个phone字段。

其次,修改t_user_his表添加一个phone字段与t_user字段顺序一致。

好了,两步就可以实现字段的自由添加、修改或者删除,不需要修改任何应用程序代码,也不再需要复杂的部署、测试、上线流程,仅在数据库中完成操作就可以了。

上述方法,修改一个字段就要记录整条数据到历史表,会占用较多的空间,要么就把字段写死。具体如何选择还是要分析系统的业务要求,不可盲目照搬。

巧用*_his表记录操作历史的更多相关文章

  1. MySQL数据库(3)_MySQL数据库表记录操作语句

    附: MYSQL5.7版本sql_mode=only_full_group_by问题 .查询当前sql_mode: select @@sql_mode .查询出来的值为: set @@sql_mode ...

  2. Django中ORM简介与单表数据操作

    一. ORM简介  概念:.ORM框架是用于实现面向对象编程语言种不同类型系统的数据之间的转换 构建模型的步骤:重点 (1).配置目标数据库信息,在seting.py中设置数据库信息 DATABASE ...

  3. Django之mysql表单操作

    在Django之ORM模型中总结过django下mysql表的创建操作,接下来总结mysql表记录操作,包括表记录的增.删.改.查. 1. 添加表记录 class UserInfo(models.Mo ...

  4. Mycat读写分离、主从切换、分库分表的操作记录

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  5. excel vba 实现跨表单(sheet) 搜索 - 显示搜索行记录搜索历史

    前两天,一个朋友问我,有没有办法在excel里实现一个表单里是原始数据,在另一个表单里显示搜索到的行,搜索关键词可用~分隔开,并把搜索历史记录下来? 我想了想,用vba实现肯定可以啊,但是我又在想,有 ...

  6. oracle中查找某用户执行某张表的操作操作记录

    转载:http://www.cnblogs.com/nizuimeiabc1/p/9441937.html 1,首先查找表的操作记录 select * from v$sqlarea a where a ...

  7. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  8. ORM多表操作之创建关联表及添加表记录

    创建关联表 关于表关系的几个结论 (1)一旦确立表关系是一对多:建立一对多关系----在多对应的表中创建关联字段. (2)一旦确立表关系是多对多:建立多对多关系----创建第三张关系表----id和两 ...

  9. MySQL(单表的表记录的操作)

    一.表记录的增删改查 1.增加表记录 <1>插入一条记录: insert [into] tab_name (field1,filed2,.......) values (value1,va ...

随机推荐

  1. 2.13.3:获取请求模板(Core Data 应用程序实践指南)

    可以不用手动写谓词,用Xcode的Data Model Designer.只是要用到AND .OR等逻辑组合时,还得用代码写谓词. 程序示例操作如下: 选中Model.xcdatamodeld 点击E ...

  2. Struts2的拦截器----Dog实例

    拦截器是一个类,这个类包含方法,用来解决DRY规则,即代码复用的问题.如果不调用拦截器,代码中需要显示通过代码调用目标方法,定义了拦截器,系统就会自动执行.大部分时候,拦截器方法都是通过代理的方式调用 ...

  3. TortoiseSVN使用简介

    TortoiseSVN使用简介 2009-04-24 来源: dev.idv.tw 1.安装及下载client 端 2.什么是SVN(Subversion)? 3.为甚么要用SVN? 4.怎么样在Wi ...

  4. C++编程之面向对象的三个基本特征

    面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...

  5. Zookeeper以Windows服务安装运行

    1.下载的Zookeeper是.cmd的批处理命令运行的,默认没有提供以windows服务的方式运行的方案 下载地址:http://zookeeper.apache.org/ 2.下载prunsrv ...

  6. HDU4474

    Yet Another Multiple Problem Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K ...

  7. (汉化改进作品)BruteXSS:Xss漏洞扫描脚本

    今天给大家进行汉化改进的事一款脚本工具:BruteXSS,这款脚本能自动进行插入XSS,而且可以自定义攻击载荷. 该脚本也同时提供包含了一些绕过各种WAF(Web应用防护系统)的语句.   0×01简 ...

  8. WPF DEV CellTemplateSelector(一个正确使用DevExpress CellTemplateSelector的Demo)

    说明 我在项目中根据需求需要用到WPF Dev CellTemplateSelector时,遇到不少坑.曾一度想要放弃使用模板转换器,但又心有不甘,终于在不断努力下,达到了需求的要求.所以写下来和大家 ...

  9. css实现页面居中的一种方法

    在网页制作的过程中,为方便读者的阅读,会把网页内容限定在一个较小的方框中,并居中显示,如何实现这一功能呢? 1)把正文放在一个<div>标签中,只要这个标签居中整个网页就居中了. < ...

  10. C++ 头文件系列(iosfwd)

    简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...