用版本控制工具将数据库版本化(转)
原文地址:http://blog.csdn.net/tywo45/article/details/2480078
1、概述
版本化数据库的起点——创建一个数据库Schema基线,这个基线是一些数据库脚本(包括create table,alter table,drop table,insert data,update data,delete data等)。这些脚本可以位于同一.sql文件中,也可根据其它规划分别位于不同文件中,例如将视图脚本,初始化数据脚本,建表脚本分别置于不同的文件中。
2、版本化数据库过程
数据库版本化与代码版本化的区别在于数据库中的生产数据是现场(即用户)创造的,当我们的表结构发生改变时,不能直接用drop table然后再create table,因为这样会导致生产数据丢失。而代码则完全由开发人员创造,可以用完全覆盖的方式升级。由于这点不同,致使数据库在版本化的过程中必然要采用与代码不同的方法。
软件过程有一个过程方法叫迭代过程。对数据库的版本化,我觉得也可以采用这种类似的方法------后一个版本的脚本依赖于前一个版本的脚本,即当你要把数据库升级到第n个版本时,你必须先把数据库升级到第(n-1)个版本,以此递归。方法很简单,但实际的过程并不会太顺利,设想以下一个场景来描述一些常见的困难和问题。
人力系统在V2.0.14版本时,有一张表叫demo_user,这张表有两个字段id和name,在我们进行V2.0.16版本的开发时,用户提出了要有cn_name(中文名)信息,并且这个信息不允许为空,如果为空,则必须用“无中文名”显示。这是个很简单的需求,我们只需要在demo_user表中添加一个cn_name字段即可------alter table demo_user add cn_name varchar2(64) not null;这个看似没有错误的语句,实际上是行不通的-----因为现场的这张表是有数据的,我们执行这条语句时会报下图所示的错误。
有经验的程序员可能想到了解决方法------将本来一条可以搞定的SQL分成三条,分别为:
alter table demo_user add cn_name varchar2(64) null; update demo_user set cn_name = '无中文名'; alter table demo_user modify cn_name varchar2(64) not null;
再设想,在V2.0.16版本时,日本有家公司要用我们公司的人力系统,我们的数据库如何直接从无到V2.0.16版本?
很容易想到的一个方法是利用递归法,从第一个版本的脚本开始跑,一直跑到V2.0.16。如果我们中间经历了1000个版本,那就跑1000遍吧。实施的要哭了!面对重复性劳动时,人们都会抽象出一种比较好的方法来处理,就像设计模式中的状态模式代替无穷的if else语句一样,我们用各版本的全量脚本来代替增量脚本。这话不太好懂,以上面场景的demo_user表为例来说明一下吧。
以增量脚本的形式,我们会有三条SQL:
alter table demo_user add cn_name varchar2(64) null; update demo_user set cn_name = '无中文名'; alter table demo_user modify cn_name varchar2(64) not null;
但以全量脚本的形式,我们只有一条SQL:
create table demo_user ( ID VARCHAR2(18) not null, NAME VARCHAR2(60) not null, CN_NAME VARCHAR2(64) not null );
看到上面的全量和增量,有何感想?是不是觉得全量脚本只能用于新增局点,而已有局点,只能用增量脚本?是的,全量脚本就是给新增局点用的,但是目前,我觉得我们还不需要提供全量脚本------原因是,维护全量脚本给我们带来的实惠要远远少于我们的付出。
再设想一个场景,日本局点不需要cn_name,他需要的是jp_name(日本名字)--------都说日本人bt,不过这个需求一点也不bt。如何做到呢?… …不累赘了,直接地说吧,此场景说明了,我们的脚本需要做到差异化控制,所以差异化控制功能必须纳入到控制范围,至于如何做到差异化控制?接着看吧!
以上说得哆嗦了点,下面说说我们将数据库版本化后,在VSS(或其它版本控制软件工具)下的目录结构吧!见下图,相信图来得够直接了,俺就不哆嗦了:
图2.1
3、问题列表
4、数据库版本管理产品
- SQL Source Control
- DBV数据库版本管理工具
- Flyway
- dbdeploy
- liquibase
5、后记
数据库版本化看似是个可有可无的过程,但做好了,可以减少开发和实施的许多事情,我们的系统就是个活生生的例子。之前在newland公司的时候,开发部门也没有数据库脚本控制,上个月听说那个部门已经接近解散了。本文所阐述的方法是来自以前在ht时的经验做法,但根据以前的一些问题作了些许改进。软件公司的发展都会经历从幼稚到成熟,借鉴其它公司的成功经验,提前认识并解决问题可减少损失。
出处:http://www.cnblogs.com/madsnotes/
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。