今天讲下软件开发中最常见的历史数据迁移方式。在讲迁移之前,先简单介绍下几个基本概念。

1、什么是历史数据迁移?

简单直白地说:就是将一些创建时间比较久而且不常用的历史数据,存储到另一个地方(可以是另一个数据,也可以是另一个表),一般历史数据迁移的数据,都是不会更改了的数据,后续只可能需要查询统计而已。

2、历史数据迁移的目的

减少在用数据库的数量,因为数据量越大,数据库操作数据(包括:查询、排序等等)的时间也就越长,当一个表的数据达到上千万级以上,再来个多条件多表查询的时候,是会有响应速度慢的可能。(因为不同开发人员写的逻辑,不可能保障每个SQL都是高效率执行的SQL)

所以及时迁移走一些历史数据,是对整个系统性能的提升是有一定好处的。

3、什么时候需要做历史数据迁移?

最简单的情况,就是你感觉程序有变慢的趋势,那就可以开始考虑历史数据迁移了。

原则上,小企业服务器不多,硬件配置也不是很高的情况下,单表500万以上的数据,最好就开始慢慢迁移,别动不动就等到几千万的数据才开始迁移。

根据产生数据量的大小判断,一般保持1年左右的业务数据即可,一年前的历史数据都迁入历史上数据库。如果每天产生的数据量实在太大的话,一般就需要考虑自动分表存储,当然如果没做这个的话,可以在不影响日常业务的情况下,实时在用业务数据库只保留最近3-6个月的数据。

4、数据迁移的基本思路

1)、第一次迁移创建一个一模一样的表结构(只要第一次迁移前创建即可)

2)、按照数据的创建时间排序,把最早的数据N条数据查出,同时插入到历史数据表中。

insert into ...  select  from

3)、检测插入数据的准确性,一定要保证是N条没错。之后删除在用的业务数据库。

4)、当迁移数据中途有误时,终止程序,但不能删除在用数据库,需要开发人员核对数据。

5)、根据迁移的对性能的影响,N不能太多,最多一次5W到10W条吧(根据服务器的性能配置,推荐一次迁移1W至5W条数据影响较小)。如果要迁移大量数据,可以考虑分批执行。

5、数据迁移存储过程代码示例

代码如下:(无需过多解释,很简单的代码,一看就懂)

  1 USE [Tyingsoft.GLPS]
2 GO
3 /****** Object: StoredProcedure [dbo].[TY_SP_ApiRequestToHis] Script Date: 2021-09-16 15:35:55 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 -- =============================================
9 -- Author:
10 -- Create date:
11 -- Last Edit date:
12 -- Description: <接口请求记录表GLPS_APIREQUEST数据迁移>
13 -- =============================================
14 ALTER PROCEDURE [dbo].[TY_SP_ApiRequestToHis]
15 -- Add the parameters for the stored procedure here
16 @PreCountN int = 2000 --每次执行的条数N
17 AS
18 BEGIN
19 -- SET NOCOUNT ON added to prevent extra result sets from
20 -- interfering with SELECT statements.
21 SET NOCOUNT ON;
22
23 declare @tableDataCount int; --迁移前的数据条数
24 declare @tableDataCountHis int; --迁移前历史数据库的数据条数
25 declare @tableDataCount2 int; --迁移后的数据条数
26 declare @tableDataCount2His int; --迁移后历史数据库的数据条数
27 declare @maxCreateTime datetime; --取N条数据中最大的创建时间
28 declare @maxCreateTimeHis datetime; --历史数据库中的最大创建时间
29 declare @beginTime datetime; --开始执行时间
30 declare @endTime datetime; --执行完成时间
31 declare @execTimeMS int; --执行时间(毫秒数)
32
33 --中间步骤debugger耗时使用
34 declare @tmpBeginTime datetime; --(临时)开始执行时间
35 declare @tmpEndTime datetime; --(临时)执行完成时间
36 declare @tmpExecTimeMS int; --(临时)执行时间(毫秒数)
37
38 select @beginTime = getdate();
39
40 --迁移前:先查询数据条数
41 select @tableDataCount = count(1) from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST;
42 select @tableDataCountHis =count(1) from [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST;
43
44 print '【接口请求记录表(GLPS_APIREQUEST)数据迁移】开始执行时间:' + convert(nvarchar(50),@beginTime,20);
45 print '本次计划迁移数据条数:'+ cast( @PreCountN as nvarchar(20));
46
47 --创建一个临时公用表达式 (表中最早创建的N条数据)
48 with topNRecord (FCREATETIME)
49 as
50 (
51 select top (@PreCountN) FCREATETIME from GLPS_APIREQUEST order by FCREATETIME
52 )
53
54 --取N条数据中最大的创建时间
55 select @maxCreateTime =max(FCREATETIME) from topNRecord
56
57 print '对应迁移数据FCREATETIME为:'+ convert(nvarchar(50),@maxCreateTime,21); --日期转化为字符串格式:yyyy-MM-dd HH:mm:ss.fff
58
59
60 select @tmpBeginTime = GETDATE(); --中间步骤开始计时
61
62 --第一步:将N条数数据写入到历史数据库
63 insert into [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST
64 select * from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST where FCREATETIME <=@maxCreateTime
65
66 select @tmpEndTime = GETDATE(); --中间步骤计时结束
67 print '数据迁移,插入耗时(毫秒):' +cast( datediff(millisecond,@tmpBeginTime,@tmpEndTime) as nvarchar(20));
68
69
70 --第二步:对比历史数据库的数据
71 select @maxCreateTimeHis=max(FCREATETIME) from [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST
72
73 if @maxCreateTime = @maxCreateTimeHis
74 begin
75 select @tmpBeginTime = GETDATE(); --中间步骤开始计时
76
77 --第三步:执行完以后,再删除数据
78 delete from GLPS_APIREQUEST where FCREATETIME <=@maxCreateTime
79 print '迁移后删除数据条数:' + cast( @@ROWCOUNT as nvarchar(50));
80
81 select @tmpEndTime = GETDATE(); --中间步骤计时结束
82 print '数据迁移,删除耗时(毫秒):' +cast( datediff(millisecond,@tmpBeginTime,@tmpEndTime) as nvarchar(20));
83 end
84 else
85 print '迁移后,日期校验错误,未删除数据!!!'
86
87 --迁移后:再查询数据条数
88 select @tableDataCount2 = count(1) from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST;
89 select @tableDataCount2His =count(1) from [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST;
90
91 print '迁移前GLPS_APIREQUEST的数据条数:' + cast(@tableDataCount as nvarchar(20))
92 + ',迁移后数据条数:'+cast(@tableDataCount2 as nvarchar(20))
93 + ',差额:'+cast((@tableDataCount2-@tableDataCount) as nvarchar(20));
94
95 print '迁移前His.GLPS_APIREQUEST的数据条数:'
96 + cast(@tableDataCountHis as nvarchar(20))
97 +',迁移后数据条数:'+cast(@tableDataCount2His as nvarchar(20))
98 + ',差额:'+cast((@tableDataCount2His-@tableDataCountHis) as nvarchar(20));
99
100 print '注意:正式环境一直有数据变动,所以会有一定的偏差!';
101
102
103 select @endTime = GETDATE();
104 print '总耗时(毫秒):' +cast( datediff(millisecond,@beginTime,@endTime) as nvarchar(20));
105
106
107 END

我们在测试数据库中来简单执行下试试效果:

6、使用场景特别说明

此方式是采用 insert into ... select from 的方式进行数据迁移。这个思路由于是最简单的数据迁移逻辑,仅适用于小数据量的情况(一般表数据低于500万),当数据量大于500万之后千万别用此方法,因为此时的insert into ... select from 会执行很慢,有很大可能会影响正式环境的运行。

还有就是此方法,由于是SQL直接访问数据库,所以要求当前业务库和历史数据都能访问(也就是同一个数据库实例),如果异地不同的数据库也没办法处理。

所以此方法仅适用于简单的历史数据迁移场景,使用前提有限,适合小项目使用。

对于大数据量的(单表1千万以上的数据),又不能影响当下业务性能指标的数据迁移方式,请看下篇文章介绍。

使用SQL SERVER存储过程实现历史数据迁移的更多相关文章

  1. sql server存储过程修改,存储到mysql笔记

    由于有些项目要迁移到mysql上,数据迁移用MySQLWorkbench就能很好的迁移,最难的是存储过程之类的. 下面是sql server存储过程和mysql存储过程的转化: SQL SERVER: ...

  2. SQL Server存储过程中使用表值作为输入参数示例

    这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...

  3. SQL Server存储过程Return、output参数及使用技巧

    SQL Server目前正日益成为WindowNT操作系统上面最为重要的一种数据库管理系统,随着 SQL Server2000的推出,微软的这种数据库服务系统真正地实现了在WindowsNT/2000 ...

  4. SQL Server 存储过程(转载)

    SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这 ...

  5. 14、SQL Server 存储过程

    SQL Server 存储过程 存储过程类似函数,可以重复使用.相对于函数,存储过程拥有更强大的功能和更高的灵活性. 存储过程中可以包含逻辑控制语句和数据操作语句,可以接受参数,输出参数,返回单个值或 ...

  6. (摘录)SQL Server 存储过程

    文章摘录:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110862.html SQL Server 存储过程 Transact-SQL中的存储过程 ...

  7. Sql Server 存储过程中查询数据无法使用 Union(All)

    原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...

  8. Yii2.0调用sql server存储过程并获取返回值

    1.首先展示创建sql server存储过程的语句,创建一个简单的存储过程,测试用. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE P ...

  9. SQL Server tempdb 数据库位置迁移

    SQL Server tempdb 数据库位置迁移 --查看物理位置 SELECT name, physical_name FROM sys.master_files WHERE database_i ...

随机推荐

  1. Shell-14-常用命令和工具

    常用命令 有人说 Shell 脚本是命令堆积的一个文件, 按顺序去执行 还有人说想学好 Shell 脚本,要把 Linux 上各种常见的命令或工具掌握了,这些说法都没错 Shell 语言本身在语法结构 ...

  2. 手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(四)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 这一篇文章主要实现路由组功能.实现路由 ...

  3. Oracle 11g数据库下载安装教程

    今天重装系统之后发现甲骨文的网站变化较大,下载安装废了一点时间,留下个笔记为以后再装留作参考.本教程是win10,64位系统环境下 1.下载 下载的时候需要登陆甲骨文账号,如果没有的话申请一个也挺快. ...

  4. SQL 练习25

    查询同名学生名单,并统计同名人数 SELECT sname,COUNT(sname) 同名人数 from Student GROUP BY sname HAVING COUNT(sname)>1

  5. Git在IDEA中的日常使用

    1.Git介绍Git对于做开发的小伙伴并不陌生,Git是现在比较流行的版本控制工具.Git的仓库分为本地仓库和远程仓库,当代码开发完成后,先提交(commit)到本地仓库,再推送(push)到远程仓库 ...

  6. Spring-Boot注入自定义properties文件配置

    创建wzq.properties wzq.properties注入User实体类中 @PropertySource(value = "classpath:wzq.properties&quo ...

  7. .net core 微服务参考文章

    网址: https://www.cnblogs.com/edisonchou/p/9124985.html Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.Consul基础介绍 Co ...

  8. 深入浅出Mybatis系列(十)---延迟加载

    一.延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 延迟加载:先 ...

  9. 阿里云sql监控配置-druid

    今天我们说说数据源和数据库连接池,熟悉java开发的同仁应该都了解C3PO,在这里不做过多的赘述了,今天我们说的是阿里DRUID,druid是后起之秀,因为它的优秀很快占领了使用市场,下边我们一起来看 ...

  10. (int)a、&a、(int)&a、(int&)a的区别,很偏僻的题

    (int)a.&a.(int)&a.(int&)a的区别,很偏僻的题 #include <iostream> #include <stdio.h> #i ...