关于历史数据迁移这事,相信很多数据库管理员都经常要面对,因为应对的场景和数据量的不同,数据迁移方法和技术也
五花八门;在一个数据量不大的表上迁移数据一般都不会有什么问题,一旦表的数据量增大,而且应用对这个表访问非常频繁时,
那如何有效的迁移数据就会是一件很有讲究的事。
迁移时先考虑以下几点要求:
如何设计历史数据保存方法;
如何将数据搬移到历史表中,如何将原表的数据删除;
在线系统要求在数据搬移时,对系统影响很小;
Job什么时间运行合适;数据量变大时,搬移时间是否足够;
数据搬移,采用with(nolock)可能造成重复数据,使得搬移过程出错,如何处理比较好;
第一:设计历史数据保持方法:
这个是个比较泛的概念,不同的公司使用的方式都不一样,常见有以下几种:
简单的历史表方式:
其实就是在库中新建一个同结构的历史表,如:Product_History,然后将历史数据都放入到这个表中,一般适合数据量不
大的情况;
优劣:优点是比较简单,便于维护,查询的时候通过View将两个表Union起来;缺点是如果数据量比较大时,会有很大的
性能问题(包括查询和插入);
按日期新建历史表:
可能是按一个月或者一年新建一个历史表,如:Product_2010、Product_2011、Product_2012…等,然后将不同时期的
历史数据存放到不同的历史表中;这个方式比较常见,查询的时候通过View将这些表Union All起来。
优劣:优点是按日期分表后,会将数据量横向切小,单个表的数据量一般不会太大,处理起来性能比较好;缺点是维护比较
麻烦,尤其是有字段的增删改的时候,所有的历史表都需要跟着修改。
数据仓库存放:
这种方式很多有BI部门的公司采用,会将历史数据和当前数据都定期存放到数据仓库中,不仅可以给BI提供制作报表的数据,
前台用户查询历史数据,APP程序就可以直接定位到仓库去查询,不影响产品环境。
优劣:优点很明显,不仅解决了历史数据查询对产品环境的影响和BI报表数据来源的问题,而且减轻了生产库保存这些历史数
据的负担;缺点是需要有BI部门,也就意味着需要相关的软、硬和人员的投入。
第二: 数据插入和删除:
数据插入这个还是比较好解决的,我们可以直接用insert插入,也可以用BCP,Bulk Insert、SSIS等方式;数据删除在数据量
比较大的时候比较棘手,主要是要权衡系统影响和速度的问题,如果每次删除的数据量比较大,势必会对系统使用者造成影响,如果
每次删除的数据量比较小,可能需要比较长的时间才能完成(分区表有直接删掉某个分区的操作,这样可以不用删除数据,直接删掉
分区就行,在此不做说明,可以参考相关文档);
第三: 系统影响的考虑:
这个和第二点相关,主要是处在系统删除的时候,需要考虑到锁的情况,避免数据库出现大批量的阻塞。
第四: Job运行时间和预计的搬移时间控制:
JOB运行时间毫无疑问是要放到系统业务的低峰时期(一般都是晚上),不过前期我们应该知道我们的系统在什么时间段内业务
比较少,这段时间里面就适合做数据的搬移操作;控制搬移时间,这个要求我们对数据搬移进行控制,如果达到某个时间点(预计业
务开发繁忙了),数据还没有搬移完成,那么应该中断搬移过程,以免影响到业务的正常进行;如果出现这种数据不能按时搬移完成
的情况,意味着需要调整搬移的过程,或者使用更高效的方法,防止历史数据越积越多。
第五:主键冲突问题:
基于对系统的影响考虑,我们一般在查询数据时都采用了With(nolock) 的方式,而数据库在默认的Read Commited隔离级
别下,加上With(nolock) 效果和Read UnCommited一样,这样在搬移数据时,可能会造成将还没有提交的数据搬移到历史表的情
况,在下次运行时,便产生了主键冲突的问题;有以下几种方法能避免此种情况:
搬移时不加With(nolock),考虑到对系统的影响,一般不采用;
历史表去掉主键,但是我们的历史数据是需要查询的,这样会造成很大的性能问题;
插入到历史表时先做判断,只插入历史表中不存在的数据,这个方法可行,但是如果历史数据表很大,判断的时间将会很长,不是最优的方法;
利用索引创建时的参数设置ignore_dup_key,将其设置为ON,这样就可以将重复的记录直接过滤掉,这种方法比较理想(后面例子有说明)。
我们以下面的两个表为例,对一些常用的数据搬移方法(将相关的方法建到JOB或者SP里面调用就行了),进行说明:
复制代码
--Master table
create table Product
(
Id int identity(1,1) primary key,
Name varchar(100),
Product_Desc varchar(1000),
Price decimal(12,2),
CreateTime datetime,
UpdateTime datetime,
Statu tinyint
)
--index
create index ix_createtime on Product(CreateTime) with(fillfactor=90,online=on)
--History
create table Product_History
(
Id int primary key, --没有自增属性
Name varchar(100),
Product_Desc varchar(1000),
Price decimal(12,2),
CreateTime datetime,
UpdateTime datetime,
Status tinyint
)
--index
create index ix_createtime on Product_History (CreateTime) with(fillfactor=90,online=on)
复制代码
No1. 简单的数据搬移:
简单的历史数据迁移方法,我们直接新建一个同结构的表,命名为表名加History,然后按照条件,每天搬移一部分数据到历史表中即可;
例如:我们将下面Product表的数据搬移到Product_History历史表中:
复制代码
--搬移条件
--10天前,Status=0的Product
insert into Product_History
select * from Product with(nolock)
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
--删除条件
delete from Product
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
复制代码
No2. 方法一的改进:
对于数据量不大的表,我们为节省时间,可以直接把搬移和删除两个步骤放到一起来进行,方法如下:
--合并搬移和删除条件
delete a
output deleted.* into Product_History
from Product a
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
No3. 分步搬移法(减轻对系统影响):
方法一和二在数据量比较小时是没有问题的,搬移过程能很快完成,但是一旦数据量变大,数据搬移可能需要一段时间才能完成的情况
下,如果再采用这种方式,势必对访问这个表的APP造成大量阻塞,这个是在线系统不能接受的,于是我们不得不把系统影响考虑进来,
把大的数据量分批次来搬移,方法如下:
复制代码
--------------------------分步搬移---------------------------------
while(1=1)
begin
declare @productid table
(
id int primary key
)
insert into @productid
select top 1000 id from Product with(nolock)
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
if exists(select 1 from @productid )
begin
--搬移条件
insert into Product_History
select * from Product with(nolock)
where id in(select id from @productid)
--删除条件
delete from Product
where id in(select id from @productid)
waitfor delay '00:00:02'
end
else
break;
end
--------------------------------------------------------------------
---------------------------分步搬移,合并搬移和删除条件------------------
--分步搬移,合并搬移和删除条件
while(1=1)
begin
delete top (1000) a
output deleted.* into Product_History
from Product a
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
if @@ROWCOUNT=0
break
else
waitfor delay '00:00:02' --delay 2s
end
---------------------------------------------------------------------
复制代码
No4. 控制搬移时间:
我们在第三步的基础上做修改,为了防止搬移作业在业务高峰时间还在运行,阻塞业务操作,我们需要在搬移进行到某个时间点时,
中断搬移作业的运行,方法如下:
复制代码
---------------------------7点后终止运行------------------
while(1=1)
begin
delete top (1000) a
output deleted.* into Product_History
from Product a
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
if @@ROWCOUNT=0 or datepart(HOUR, GETDATE())>=7 --7点后终止运行
break
else
waitfor delay '00:00:02' --delay 2s
end
---------------------------------------------------------------------
复制代码
No5. 了解搬移的进度:
有时候我们看到搬移JOB一直在运行,但是没有办法知道它要运行到什么时候才能运行完,只能干等,于是我们有对某些搬移作业进
度情况作了解的需求,我们再来更改脚本:
复制代码
--先创建一个搬移记录表
create table temp_history_2011_12_01
( prd_id int primary key,
is_del bit --是否搬移完成
)
--------------------------了解搬移进度---------------------------------
truncate table temp_history_2011_12_01
--所有需要搬移的数据插入到表中
insert into temp_history_2011_12_01
select id,0 from Product with(nolock)
where CreateTime<convert(varchar,DATEADD(day,-10,GETDATE()),112) and Status=0
while(1=1)
begin
declare @productid table
(
id int primary key
)
--1000
insert into @productid
select top 1000 prd_id from temp_history_2011_12_01 where is_del=0
if exists(select 1 from @productid )
begin
--搬移条件
insert into Product_History
select * from Product with(nolock)
where id in(select id from @productid)
--删除条件
delete from Product
where id in(select id from @productid)
--update is_del
update temp_history_2011_12_01 set is_del=1
where prd_id in(select id from @productid)
waitfor delay '00:00:02'
end
else
break;
end
truncate table temp_history_2011_12_01
---------------------------------------------------------------------
--------------假定已运行时间是5小时,估计剩余时间-------------
declare @fin_count int,@need_count int
select @fin_count=COUNT(0) from temp_history_2011_12_01 with(nolock) where is_del=1
select @need_count=COUNT(0) from temp_history_2011_12_01 with(nolock) where is_del=0
select @need_count*1.0/@fin_count*5
---------------------------------------------------------------------
复制代码
No6. 避免重复键冲突:
我们先来看下ignore_dup_key作用的描述:使涉及多行的insert语句在有重复键值的错误时不会引起整个语句的回滚,那个导致不唯一的行会被舍弃, 而其他的行都将被插入或者更新,同样可以在创建主键约束时,使用该选项。
于是,我们可以在历史表创建时,在主键上使用这个选项,例如:
复制代码
CREATE TABLE [dbo].[Product_History](
[Id] [int] NOT NULL,
[Name] [varchar](100) NULL,
[Product_Desc] [varchar](1000) NULL,
[Price] [decimal](12, 2) NULL,
[CreateTime] [datetime] NULL,
[UpdateTime] [datetime] NULL,
[Status] [tinyint] NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
复制代码
这样就可以避免因主键冲突导致数据搬移JOB的失败了。
以上是就SQL层面的历史数据搬移的一些方法,还有BCP、Bulk Insert、SSIS等方法可以使用,在此不做说明;以上方法加以
调整,便可以做成比较通用的数据搬移方法,包括控制搬移记录数、控制搬移时间、了解搬移进度等问题都可以得到灵活控制,让数
据搬移顺起来。
分享到:
相关推荐
总之,历史数据迁移需要综合考虑各种因素,如数据保存策略、操作时机、系统影响和冲突处理,以确保数据迁移的高效性和系统稳定性。对于大型数据库,合理的设计和实施策略是确保业务连续性和数据完整性的关键。
历史数据迁移测试是软件测试领域中一个特殊且重要的环节,主要涉及将旧系统中的历史数据迁移到新系统或新数据库中,确保数据的准确性和可用性。以下是对这个主题的详细解析: 首先,进行历史数据迁移测试前,需明确...
在IT行业中,数据库管理是一项至关重要的任务,而SQL数据迁移工具正是解决这一问题的有效手段。本文将深入探讨SQL数据迁移工具的功能、应用场景以及常见的迁移策略。 SQL数据迁移工具,如标题所示,是一种能够帮助...
利用导出功能实现历史数据迁移 在本次迁移方案中,我们将讨论如何 利用导出功能实现历史数据迁移,以腾出数据库的有效空间,提高系统和数据备份工作效率。以下是相关知识点的总结: 1. 需求分析 在进行数据迁移...
"系统历史数据迁移专项方案" 系统历史数据迁移专项方案是指在新老系统迁移和整合过程中,以确保业务办理顺利、平稳过渡到新系统中进行的专项方案。该方案旨在解决新老系统之间的切换问题,确保新开发系统和保留老...
本文将对数据迁移整合方案进行详细的解释和分析,从历史数据的迁移整合到新系统的开发和整合,讨论新系统迁移和整合的需求分析、系统整合目标、系统换方案等几个方面。 一、历史数据的迁移整合 历史数据的迁移整合...
【系统历史数据迁移方案】 系统历史数据迁移是一个复杂的IT任务,尤其当涉及到多个异构系统时,需要精细的规划和执行。在这个方案中,我们关注的是如何从旧系统平滑过渡到新系统,并确保所有关键数据的准确无误。新...
在这个报告中,我们关注的是如何有效地进行历史数据迁移和不同系统间的整合,以确保业务的连续性和系统的稳定性。 首先,新老系统迁移整合的需求分析是整个过程的基础。系统迁移,即系统切换,涉及到数据资源整合、...
这里我们关注的是使用Shell脚本来实现MySQL从原表到历史表的数据迁移。这种自动化的方法可以帮助我们高效、准确地处理大量数据,同时减少人为错误。 首先,让我们深入理解`shell`脚本。Shell是Linux和Unix系统中的...
系统历史数据迁移方案.pdf
- LSMW是一个集成在SAP系统中的工作台,用于从非SAP源系统向SAP系统导入大量历史数据,支持多种数据源格式,如Excel、CSV等。 1.3 **支持的R/3版本** - LSMW支持多种SAP R/3版本,确保与不同系统的兼容性。 1.4 ...
1. **数据迁移**:将数据从旧系统迁移到新系统,或者在不同数据库之间迁移数据。 2. **数据整合**:从多个异构数据源中抽取数据,整合成统一的数据视图。 3. **数据清洗**:去除数据中的错误、重复或不一致信息,...
知识管理系统数据迁移通用方案是指在信息化建设过程中,为了确保新系统的顺利运行,需要将原有系统中的历史数据迁移到新系统中的一种方法。这种方法主要适用于一套旧系统切换到另一套新系统,或多套旧系统切换到同...
8. **版本控制**:支持版本管理,方便团队协作和维护历史版本,确保在不同阶段的数据迁移任务能够顺利进行。 9. **错误处理和调试**:提供详细的日志和调试工具,帮助开发者快速定位和解决问题,提高了问题解决的...
ORA_ROWSCN伪列在Oracle历史数据迁移中的应用研究 Oracle数据库系统中,数据迁移是不可避免的,特别是在大型企业中,数据库系统的数据量会随着时间的推移不断增长。为了解决这个问题,Oracle提供了多种数据迁移...
本方案旨在满足用户招标需求,实现应用和新建业务平台的一体化集成,并确保在迁移过程中,工作不会中断,历史数据得以完整保留。迁移过程需与原系统承建公司进行协作,同时需要处理好与运营商接入链路的转换以及数据...
Hyperion生命周期管理 LCM迁移文档,适用于海波龙项目实施
横向划分以产生数据的时间为划分依据,优先考虑迁移与当前日期较近的数据,这样可以尽可能缩小新系统由于历史数据问题对用户的影响,而那些相比照拟长远的数据可以分批次进展数据迁移。 1.1.2 纵向划分 纵向划分以...