使用SQL SERVER存储过程实现历史数据迁移方式
作者:飞天心宏 发布时间:2024-01-13 04:07:40
今天讲下软件开发中最常见的历史数据迁移方式。在讲迁移之前,先简单介绍下几个基本概念。
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千万以上的数据),又不能影响当下业务性能指标的数据迁移方式,请看下篇文章介绍。
来源:https://www.cnblogs.com/feitianxinhong/p/15310913.html


猜你喜欢
- #/usr/bin/env python#-*- coding:utf-8 -*-"""1.解析 cronta
- 介绍在机器视觉领域的深度学习中,每个数据集都有一份标注好的数据用于训练神经网络。为了节省空间,很多数据集的标注文件使用RLE的格式。但是神经
- 好久没有学python了,反正各种理由吧(懒惰总会有千千万万的理由),最近网上学习了一下selenium,实现了一个简单的自动登录网页,具体
- 主题介绍pyecharts里面有很多的主题可以供我们选择,我们可以根据自己的需要完成主题的配置,这样就告别了软件的限制,可以随意的发挥自己的
- 本文实例为大家分享了python批量复制图片到文件夹的具体代码,供大家参考,具体内容如下直接上代码:# -*- coding: utf-8
- Python模块,简单说就是一个.py文件,其中可以包含我们需要的任意Python代码。迄今为止,我们所编写的所有程序都包含在单独的.py文
- 一共4个页面:form.asp; chk.asp; num.asp; count.asp得到一个随即数字。加密
- golang判断元素是否在数组内众所周知,golang里没有像python的in来判断元素是否在list里存在,可替代的办法是将list放到
- 一、概念梳理链表是计算机科学里面应用应用最广泛的数据结构之一。它是最简单的数据结构之一,同时也是比较高阶的数据结构(例如棧、环形缓冲和队列)
- 通过《SQL Server 数据库备份和还原认识和总结(一)》,相信您对数据备份和还原有了一个更深入的认识,在上文中我没有对事务日志做剖析,
- 熟悉SQL SERVER 2000的数据库管理员都知道,其DTS可以进行数据的导入导出,其实,我们也可以使用Transa
- 本文实例讲述了thinkphp3.x连接mysql数据库的方法。分享给大家供大家参考,具体如下:惯例配置文件:ThinkPHP/conf/c
- 本文实例讲述了Python找出序列中出现次数最多的元素。分享给大家供大家参考,具体如下:问题:找出一个元素序列中出现次数最多的元素是什么解决
- 这里要注意的是js的时间戳是13位,php的时间戳是10位,转换函数如下: var nowtime = (new Date).getTime
- 本文实例讲述了Oracle例外用法。分享给大家供大家参考,具体如下:一、例外分类oracle将例外分为预定义例外、非预定义例外和自定义例外三
- 首先非常感谢作者针对bootstrap table分页问题进行详细的整理,并分享给了大家,希望通过这篇文章可以帮助大家解决Bootstrap
- 今天给大家讲的是ASP给图片加水印的知识ASP给图片加水印是需要组件的…常用的有aspjpeg和中国人自己开发的wsImage…前者有30天
- SQL Server 2005附加数据库文件时出现了Read-Only错误,附加的时候,系统提示mdf文件为只读,可是打开文件属性,这个属性
- 项目结构├── node_modules # 项目依赖包目录├── build &nb
- 学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了!这里就简单讨论下python的几种装饰模