数据库重构11之转换

本文介绍了数据库重构的基本方法,包括插入数据、引入新列、引入新表、引入视图和更新数据等转换方式,并详细阐述了每种转换的具体实现步骤。

转换是一种变更,它为数据库schema增加了新的特征,从而改变了数据库shcema的语义。

1、插入数据

在已有表中插入数据。

动机

在对表设计进行结构变更之后,通常需要进行“插入数据”变更。

  • 重新组织表。如果进行了“表改名”、“合并表”、“拆分表”、“删除表”等重构,可能必须进行“”,在原有的表中重新组织数据。
  • 提供静态查找数据。
  • 创建测试数据。

可能的折衷

在表中插入新数据可能比较麻烦,特别是如果打算插入查找数据,而这些数据又被一个或多个其他的表参照时。

shcema更新的方法

为了更新数据库schema,必须执行以下步骤:

  1. 确定要插入的数据。包括确定所有的依赖关系。
  2. 确定数据的目的地。
  3. 确定数据源。来自其他表还是手工插入。
  4. 确定转换需求。插入目标表之前,是否需要转换。

数据迁移的方法

如果需要插入少量的数据,可能只需要一个简单的SQL脚本就足够了。对于大量的数据,需要更复杂的方式,如Oracle的SQLLDR或批量数据加载工具。

图1展示了如何向AccountType表中插入一条新记录,代表经纪(brokerage)账户。

Insert Data Example

图1 插入一条新AccountType

下面的代码展示了向AccountType表插入数据的DML:

INSERT INTO AccountType(AccountTypeID,Name,EffectiveDate)
     VALUES (6,'Brokerage','Feb 1 2007');

访问程序更新的方法

如果“插入数据”是由另一类数据库重构引起的,应该按照那种重构更新应用。

如果“插入数据”是为了支持额外的数据,有可能外部应用代码需要进行修改。例如,在图1中,我们将“Brokerage”插入到AccountType表中。可能需要在WHERE子句中不需要这个值的情况下去掉它,如下面的代码所示。

也可以通过“引入视图”重构来创建一个特定的视图,返回数据的子集。参见后文。

同样,可能需要更新检验数据有效性的源代码。例如,存在一些代码,规定溢价账户(premium account)可以是私人账户(private)或者货币市场账户(money market)。现在也可以是经纪账户(Brokerage)。

2、引入新列

在已有的表中引入一个新列。

动机

引入新列的原因可能包括:

  • 持久化新的属性。
  • 一次重构的中间步骤。许多重构,如“移动列”和“列改名”都包含一次引入新列的步骤。

可能的折衷

需要确保该列没有在其他地方已经存在;否则,可能因为增加了数据冗余而导致参照完整性问题。

schema更新的方法

如图2所示,只需要通过SQL命令ALTER TABLE的ADD子句引入CountryCode列。

Introduce New Column Example

图2 引入State.CountryCode列

State.CountryCode具有一个外键,参照到Country表。为了创建参照约束,需要进行“加入外键约束”重构。

数据迁移的方法

虽然这类转换本身没有数据迁移,但一项重要的任务是向该列中填充数据值。需要执行以下的步骤:

  1. 与项目涉众一起确定合适的值。
  2. 手工或者通过脚本自动填充该列。
  3. 考虑对该列进行“引入缺省值”、“删除不可空”或者“使列不可空”等重构。

下面的代码演示了用初始值“USA”填充State.CountryCode列的DML。

访问程序更新的方法

需要更新的就是在应用中使用新的列。下面的代码展示了hibernate的OR映射元数据的更新。

//Before mapping


 
 


//After mapping


 
 
                 class="Country"
               column="COUNTRYCODE"/>


3、引入新表

在现有数据库中引入一个新表。

动机

引入新表的原因可能包括:

  • 持久化新的属性。
  • 一次重构的中间步骤。许多重构,如“拆分表”和“表改名”,都包含一个引入新表的步骤。
  • 为了引入新的正式数据源。常常存在类似信息存储在多个表中,彼此之间不同步或者相互矛盾。这种情况下必须进行“使用正式数据源”重构,然后对那些非正式数据源进行“删除表”重构。
  • 需要进行数据备份。一些重构,如“删除表”和“合并表”,可能需要创建一个表保存中间数据或者作为备份。

可能的折衷

主要是需要确认引入的表没有在其他地方已经存在。通常是存在与之近似的表,重构原有的表比加入新表并包含冗余信息更容易一些。

schema更新的方法

如图3所示,只需要通过SQL命令CREATE TABLE引入CustomerIdentification。

Introduce New Table Example

图3 引入CustomerIdentification表

下面的代码展示了引入CustomerIdentification表的DDL。CustomerID列具有一个外键,参照到Customer表。

数据迁移的方法

虽然这类转换本身没有数据迁移,但一项重要的任务是向该表中填充数据值。需要执行以下的步骤:

  1. 与项目涉众一起确定合适的值。
  2. 手工或者编写脚本自动地填充该表。
  3. 考虑进行“插入数据”转换。

访问程序更新的方法

理想情况下,只需要在应用中使用新的表就可以了。但如果新表是为了替代其他的几个表,需要重构访问程序使用新表。

4、引入视图

基于数据库中已有的表创建一个视图。

动机

引入视图的原因可能包括:

  • 汇总报表数据。
  • 取代重复的读取。一些外部程序或者存储过程常常实现了相同的检索查询,可以被一个通用的只读表或者视图取代。
  • 数据安全。视图可以向终端用户提供读取数据的权限,但不提供更新的权限。
  • 封装对表的访问。通过定义可更新的视图来封装对表的访问。这样可以容易地进行类似“列改名”或“表改名”的重构,因为视图在表和应用之间增加了一个封装层。
  • 减少SQL重复。如果应用存在复杂的SQL查询,通常SQL的部分内容在许多地方是重复的。

可能的折衷

引入视图主要有两项挑战。首先,终端用户可能不能接受视图的连接性能,这就需要使用其他的方式,例如“引入只读表”重构。其次,增加新的视图将增加数据库schema的内部耦合性,如图4所示,视图定义依赖于表的定义。

Introduce View Example

图4 引入CustomerPortfolio视图

schema更新的方法

为了更新数据库schema,只需要通过SQL命令CREATE VIEW。下面的代码展示了引入CustomerPortfolio视图的DDL。

数据迁移的方法

这类转换没有数据迁移的要求。

访问程序更新的方法

如果引入视图是为了取代访问程序中的通用SQL读取代码,那么必须更新相应的代码,使用新的视图;如果是为了得到报表,应该编写新的报表,利用视图带来的便利性。

如果应用中存在重复的SQL代码,很可能存在缺陷,因为改动一处的SQL时,必须对所有重复的SQL代码进行类似的改动。例如,考虑下面这个例子:

可以看到两段代码对于活动(ACTIVE)顾客的选择是重复的。可以创建一个视图,将重复的SQL提取到视图中,这样当SQL选择活动顾客的方式发生变化时,不需要多次修改。

5、更新数据

更新现有表中的数据。

动机

可能的原因包括:

  • 表重组。如果进行了“表改名”、“列改名”、“移动列”、“拆分表”、“拆分列”、“合并表”或者“合并列”等重构,可能需要进行“更新数据”,重新组织原表中的数据。
  • 提供原来没有的数据。如果进行了“引入新列”这样的转换,需要在生产环境中为新增的列提供数据。
  • 修改参照数据。
  • 支持列变更。类似“采用标准代码”和“采用标准类型”的重构,常常需要更新该列中保存的数据。
  • 修复事务性数据。由于部署的应用或数据库的缺陷,可能得到了一些无效的结果,需要进行修复变更。

可能的折衷

更新表中的数据可能比较麻烦,特别是更新参照数据。

schema更新的方法

这类转换没有更新schema的要求。

数据迁移的方法

如果更新少量数据,可能只需要一个简单的SQL脚本就足够了。对于大量数据,需要诸如ETL工具的更复杂的方式。要考虑的问题包括:

  • 源数据是由原来的应用表提供,还是由业务用户提供?
  • 项目涉众接受这些值吗?
  • 哪些行需要更新?
  • 这些行中的哪些列需要更新?
  • 存在怎样的依赖关系?

图5展示了如何更新AccountType表。这个AccountType支持新的命名惯例,需要先测试,然后再部署到生产环境中去。

Update Data Example

图5 更新AccountType表

下面的代码展示了更新表的DDL。

访问程序更新的方法

如果“更新数据”是由另一类数据库重构引起的,外部程序应该按照那种重构进行更新。

如果是为了支持在原有的schema上改动数据,可能外部程序需要进行改动。首先,可能需要更新SELECT语句,使WHERE子句包含更新后的值。类似,可能需要更新检验数据有效性的代码。下面的视图定义展示了当“Private”账户类型改为“Private Banking”时,应用如何修改。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24945919/viewspace-745904/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24945919/viewspace-745904/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值