使用SQL SERVER存储过程实现历史数据迁移方式

 更新时间:2021年9月19日 15:27  点击:1942

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

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、数据迁移存储过程代码示例

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

USE [Tyingsoft.GLPS]
GO
/****** Object:  StoredProcedure [dbo].[TY_SP_ApiRequestToHis]    Script Date: 2021-09-16 15:35:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
-- Create date:
-- Last Edit date:
-- Description:    <接口请求记录表GLPS_APIREQUEST数据迁移>
-- =============================================
ALTER PROCEDURE [dbo].[TY_SP_ApiRequestToHis]
    -- Add the parameters for the stored procedure here
    @PreCountN int = 2000     --每次执行的条数N
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    declare @tableDataCount int;          --迁移前的数据条数
    declare @tableDataCountHis int;       --迁移前历史数据库的数据条数
    declare @tableDataCount2 int;         --迁移后的数据条数
    declare @tableDataCount2His int;      --迁移后历史数据库的数据条数
    declare @maxCreateTime datetime;      --取N条数据中最大的创建时间
    declare @maxCreateTimeHis datetime;   --历史数据库中的最大创建时间
    declare @beginTime datetime;          --开始执行时间
    declare @endTime datetime;            --执行完成时间
    declare @execTimeMS int;              --执行时间(毫秒数)

    --中间步骤debugger耗时使用
    declare @tmpBeginTime datetime;       --(临时)开始执行时间
    declare @tmpEndTime datetime;         --(临时)执行完成时间
    declare @tmpExecTimeMS int;           --(临时)执行时间(毫秒数)

    select @beginTime = getdate();

    --迁移前:先查询数据条数
    select @tableDataCount = count(1) from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST;
    select @tableDataCountHis =count(1) from  [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST;

    print '【接口请求记录表(GLPS_APIREQUEST)数据迁移】开始执行时间:' + convert(nvarchar(50),@beginTime,20);
    print '本次计划迁移数据条数:'+ cast( @PreCountN as nvarchar(20));

    --创建一个临时公用表达式 (表中最早创建的N条数据)
    with topNRecord (FCREATETIME)
    as
    (
        select top (@PreCountN) FCREATETIME from GLPS_APIREQUEST  order by FCREATETIME
    )

    --取N条数据中最大的创建时间
    select @maxCreateTime =max(FCREATETIME) from topNRecord

    print '对应迁移数据FCREATETIME为:'+ convert(nvarchar(50),@maxCreateTime,21); --日期转化为字符串格式:yyyy-MM-dd HH:mm:ss.fff


    select @tmpBeginTime = GETDATE();  --中间步骤开始计时

    --第一步:将N条数数据写入到历史数据库
    insert into [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST
    select * from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST  where  FCREATETIME <=@maxCreateTime

    select @tmpEndTime = GETDATE();   --中间步骤计时结束
    print '数据迁移,插入耗时(毫秒):' +cast( datediff(millisecond,@tmpBeginTime,@tmpEndTime) as nvarchar(20));


    --第二步:对比历史数据库的数据
    select @maxCreateTimeHis=max(FCREATETIME) from [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST

    if @maxCreateTime = @maxCreateTimeHis
       begin
            select @tmpBeginTime = GETDATE();  --中间步骤开始计时

            --第三步:执行完以后,再删除数据
            delete from GLPS_APIREQUEST where FCREATETIME <=@maxCreateTime
            print '迁移后删除数据条数:' + cast( @@ROWCOUNT as nvarchar(50));

            select @tmpEndTime = GETDATE();       --中间步骤计时结束
            print '数据迁移,删除耗时(毫秒):' +cast( datediff(millisecond,@tmpBeginTime,@tmpEndTime) as nvarchar(20));
        end
    else
        print '迁移后,日期校验错误,未删除数据!!!'

    --迁移后:再查询数据条数
    select @tableDataCount2 = count(1) from [Tyingsoft.GLPS].dbo.GLPS_APIREQUEST;
    select @tableDataCount2His =count(1) from  [Tyingsoft.GLPS_His].dbo.GLPS_APIREQUEST;

    print '迁移前GLPS_APIREQUEST的数据条数:' + cast(@tableDataCount as nvarchar(20))
     + ',迁移后数据条数:'+cast(@tableDataCount2 as nvarchar(20))
     + ',差额:'+cast((@tableDataCount2-@tableDataCount) as nvarchar(20));

    print '迁移前His.GLPS_APIREQUEST的数据条数:'
    + cast(@tableDataCountHis as nvarchar(20))
    +',迁移后数据条数:'+cast(@tableDataCount2His as nvarchar(20))
    + ',差额:'+cast((@tableDataCount2His-@tableDataCountHis) as nvarchar(20));

    print '注意:正式环境一直有数据变动,所以会有一定的偏差!';


    select @endTime = GETDATE();
    print '总耗时(毫秒):' +cast( datediff(millisecond,@beginTime,@endTime) as nvarchar(20));


END

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

6、使用场景特别说明

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

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

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

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

到此这篇关于使用SQL SERVER存储过程实现历史数据迁移的文章就介绍到这了,更多相关SQL SERVER存储过程数据迁移内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • MySQL性能监控软件Nagios的安装及配置教程

    这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
  • 金额阿拉伯数字转换为中文的存储过程

    Create Procedure AtoC @ChangeMoney Money as Set Nocount ON Declare @String1 char(20) Declare @String2 char(30) ...2016-11-25
  • PostgreSQL判断字符串是否包含目标字符串的多种方法

    这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • PHP操作MSSQL存储过程修改用户密码

    存储过程在数据库的应用中我们用到的非常的多了,下面我们来看一篇关于PHP操作MSSQL存储过程修改用户密码的例子,具体的如下所示。 mssql2008 存储过程 下面可以直接...2016-11-25
  • PostgreSQL TIMESTAMP类型 时间戳操作

    这篇文章主要介绍了PostgreSQL TIMESTAMP类型 时间戳操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-26
  • 详解Mysql中的JSON系列操作函数

    新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
  • postgresql 实现多表关联删除

    这篇文章主要介绍了postgresql 实现多表关联删除操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-02
  • Postgresql 如何选择正确的关闭模式

    这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • 深入研究mysql中的varchar和limit(容易被忽略的知识)

    为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15
  • postgresql数据添加两个字段联合唯一的操作

    这篇文章主要介绍了postgresql数据添加两个字段联合唯一的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-04
  • MySQL 字符串拆分操作(含分隔符的字符串截取)

    这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
  • mysql的3种分表方案

    一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
  • Vscode上使用SQL的方法

    这篇文章主要介绍了Vscode上使用SQL的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-26
  • MySql存储过程之逻辑判断和条件控制

    具体详情请看下文小编给大家带来的知识点。同编写程序类似,存储过程中也有对应的条件判断,功能类似于if、switch。在MySql里面对应的是IF和CASE1、IF判断IF判断的格式是这样的:IF expression THEN commands [ELSEIF ex...2015-10-21
  • PostgreSQL 字符串处理与日期处理操作

    这篇文章主要介绍了PostgreSQL 字符串处理与日期处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01
  • Windows服务器MySQL中文乱码的解决方法

    我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。...2015-03-15
  • SQL Server中row_number函数的常见用法示例详解

    这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • Centos5.5中安装Mysql5.5过程分享

    这几天在centos下装mysql,这里记录一下安装的过程,方便以后查阅Mysql5.5.37安装需要cmake,5.6版本开始都需要cmake来编译,5.5以后的版本应该也要装这个。安装cmake复制代码 代码如下: [root@local ~]# wget http://www.cm...2015-03-15
  • postgresql重置序列起始值的操作

    这篇文章主要介绍了postgresql重置序列起始值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-04