全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

SQL Server实现自动循环归档分区数据脚本详解

概述

大家应该都知道在很多业务场景下我们需要对一些记录量比较大的表进行分区,同时为了保证性能需要将一些旧的数据进行归档。在分区表很多的情况下如果每一次归档都需要人工干预的话工程量是比较大的而且也容易发生纰漏。接下来分享一个自己编写的自动归档分区数据的脚本,原理是分区表和归档表使用相同的分区方案,循环利用当前的文件组,话不多说了,来一起看看详细的介绍吧。

一、创建测试数据

----01创建文件组
USE [master]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group1]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group2]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group3]
GO
ALTER DATABASE [chenmh] ADD FILEGROUP [Group4]
GO
USE [master]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile1', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile1.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group1]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile2.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group2]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile3', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile3.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group3]
GO
ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile4', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\datafile4.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group4]
GO


----02创建分区函数
USE [chenmh]
GO
CREATE PARTITION FUNCTION [Pt_Range](BIGINT) AS RANGE RIGHT FOR VALUES (1000000, 2000000, 3000000)
GO

----03创建分区方案,分区方案对应的文件组数是分区函数指定的数量+1
CREATE PARTITION SCHEME Ps_Range
AS PARTITION Pt_Range
TO (Group1, Group2, Group3, Group4);


---04创建表,指定的分区列的数据类型一定要和分区函数指定的列类型一致。
CREATE TABLE [dbo].[News](
 [id] [bigint] NOT NULL,
 [status] [int] NULL,
 CONSTRAINT [PK_News] PRIMARY KEY CLUSTERED 
(
 [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)
) ON [Ps_Range](id)

-----创建归档分区表
CREATE TABLE [dbo].[NewsArchived](
 [id] [bigint] NOT NULL,
 [status] [int] NULL,
 CONSTRAINT [PK_NewsArchived] PRIMARY KEY CLUSTERED 
(
 [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)
) ON [Ps_Range](id)

----插入测试数据
DECLARE @id INT 
SET @id=1
WHILE @id<5001000
BEGIN
 INSERT INTO News VALUES(@id,@id%2)
 SET @id=@id+1

END

可以看到当前总共有4个分区,每一个分区定义的范围区间是100万,分区4我故意多插入了200多万的数据来验证自动归档分区。

二、自动归档分区脚本

CREATE PROCEDURE Pro_Partition_AutoArchiveData
(@PartitionTable VARCHAR(300),
@SwitchTable VARCHAR(300)
)
AS
BEGIN
DECLARE @FunName VARCHAR(100),@SchemaName VARCHAR(100),@MaxPartitionValue sql_variant

---根据归档表查找对应的分区方案、分区函数、最小分区数、最大分区范围值
SELECT 
DISTINCT
@FunName=MAX(pf.name),
@SchemaName=MAX(ps.name), 
@MaxPartitionValue=max(isnull(prv.value,0))
FROM sys.partitions p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_id
inner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_id
inner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_number
inner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_id
inner join sys.partition_functions pf ON ps.function_id=pf.function_id
LEFT join sys.partition_range_values prv ON pf.function_id=prv.function_id AND prv.boundary_id=p.partition_number-pf.boundary_value_on_right
LEFT join sys.partition_parameters pp ON prv.function_id=pp.function_id and prv.parameter_id=pp.parameter_id
LEFT join sys.types t ON pp.system_type_id=t.system_type_id and pp.user_type_id=t.user_type_id
WHERE OBJECT_NAME(p.OBJECT_ID)=@PartitionTable


DECLARE @MaxId BIGINT,@MinId BIGINT,@Sql NVARCHAR(MAX),@GroupName VARCHAR(100),@MinPartitionNumber INT
SET @Sql= N'SELECT @MaxId=MAX(id),@MinId=Min(id) FROM '+@PartitionTable
EXEC sp_executesql @Sql,N'@MaxId BIGINT out,@MinId BIGINT out',@MaxId OUT,@MinId OUT

SELECT @FunName AS FunName,@SchemaName AS SchemaName,@MaxPartitionValue AS MaxPartitionValue ,@MaxId AS MaxId,@MinId AS MinId

---判断当前表的最大的id是否已经在最大的分区中
IF @MaxId>=@MaxPartitionValue
 BEGIN
 ----归档分区数据,根据表的最小值找到它所属的分区.
 SET @Sql= N'SELECT @MinPartitionNumber=$PARTITION.'+@FunName+N'('+CONVERT(VARCHAR(30),@MinId)+N')';
 EXEC sp_executesql @Sql,N'@MinPartitionNumber INT out',@MinPartitionNumber OUT
 SET @Sql=N'ALTER TABLE ' +@PartitionTable+ N' SWITCH PARTITION '+CONVERT(VARCHAR(10),@MinPartitionNumber)+ N' TO ' +@SwitchTable+ N' PARTITION ' +CONVERT(VARCHAR(10),@MinPartitionNumber);
 --PRINT @Sql
 EXEC (@Sql)
 ---修改分区方案,增加新的分区对应的文件组,根据最小的分区id找到对应的文件组。
 SELECT 
 DISTINCT
 @GroupName=ds.name
 FROM sys.partitions p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_id
 inner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_id
 inner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_number
 inner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_id
 inner join sys.partition_functions pf ON ps.function_id=pf.function_id
 WHERE pf.name=@FunName AND ps.name=@SchemaName AND p.partition_number=@MinPartitionNumber
 SET @Sql=N'ALTER PARTITION SCHEME '+@SchemaName+N' NEXT USED '+@GroupName
 --PRINT @Sql
 EXEC (@Sql)
 ---修改分区函数,增加新的分区,增加新的分区范围值,在现有的最大的值的基础上加100万(需要和现有的分区函数的范围保持一致)
 SET @MaxPartitionValue=CONVERT(BIGINT,@MaxPartitionValue)+1000000
 SET @Sql=N'ALTER PARTITION FUNCTION '+@FunName+N'('+N')'+N' SPLIT RANGE ('+CONVERT(VARCHAR(30),@MaxPartitionValue)+N')'
 --PRINT @Sql
 EXEC (@Sql)

 END


END

三、自动归档分区数据

1.首次测试

EXEC Pro_Partition_AutoArchiveData 'news','NewsArchived';

注意:每调用一次归档一个最小分区的数据。

分区表的News分区1的数据被归档到了NewsArchived表中,且创建了分区5,分区5使用的是已归档的分区1的文件组,达到了循环利用文件组的效果。

2.再调用一次归档分区脚本

当分区表最大的id小于最大的分区值时自动归档分区脚本就不会生效。所以当前的测试表数据还可以再归档分区3的数据。

3.经过一段时间的运行归档数据可能是这样的效果

Group1→Group4→Group1→.......

四、脚本注意事项

      1.@PartitionTable和@SwitchTable表必须使用同名的分区方案和分区函数,否则@SwitchTable就需要单独修改分区方案和函数,且表结构完全一致。

      2.归档的表分区列数据类型必须是INT类型,且值是自增规律.

      3.分区归档作业在备份作业后执行

      4.建议使用Right分区,Left分区会出现有的最后一个分区文件组不会循环替换,一直处于分区的最后,比如Group1,Group2,Group3,Group1,Group2,Group3,Group1,Group4。期望的应该是Group1,Group2,Group3,Group4,Group1,Group2,Group3,Group4,Group1

      5.注意我当前的每个分区大小是100万和分区函数保持一致,如果范围值不同,需要修改最末尾代码的"修改分区函数"处代码.

总结

当前自动归档分区脚本如果要拷贝去用还是得能完全理解每一段代码,根据自己的业务做适当的修改,毕竟数据是无价的!!!。最后只需要创建一个作业定期跑作业就行,重复执行也不影响。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


# sqlserver  # 分区  # sql  # server自动归档  # server  # 归档  # SQL server 2005的表分区  # SQLSERVER 表分区操作和设计方法  # SQLServer 通用的分区增加和删除的算法  # SQL Server根据分区表名查找所在的文件及文件组实现脚本  # 分区表  # 自己的  # 的是  # 测试数据  # 循环利用  # 也不  # 好了  # 还可以  # 首次  # 是这样  # 说了  # 不多  # 有一定  # 就行  # 达到了  # 可以看到  # 只需要  # 这篇文章  # 无价  # 比较大 


相关文章: 建站主机选购指南:核心配置与性价比推荐解析  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  如何在局域网内绑定自建网站域名?  建站主机选购指南:核心配置优化与品牌推荐方案  家庭建站与云服务器建站,如何选择更优?  如何快速搭建二级域名独立网站?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  如何在云主机上快速搭建多站点网站?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  如何用西部建站助手快速创建专业网站?  如何在建站主机中优化服务器配置?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  阿里云网站制作公司,阿里云快速搭建网站好用吗?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  如何零基础在云服务器搭建WordPress站点?  智能起名网站制作软件有哪些,制作logo的软件?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  盐城做公司网站,江苏电子版退休证办理流程?  如何零成本快速生成个人自助网站?  建站主机类型有哪些?如何正确选型  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  建站之星安装模板失败:服务器环境不兼容?  建站之星代理如何获取技术支持?  如何用PHP工具快速搭建高效网站?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  如何获取PHP WAP自助建站系统源码?  威客平台建站流程解析:高效搭建教程与设计优化方案  高性能网站服务器部署指南:稳定运行与安全配置优化方案  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  建站主机功能解析:服务器选择与快速搭建指南  定制建站哪家更专业可靠?推荐榜单揭晓  网站制作模板下载什么软件,ppt模板免费下载网站?  建站之星安装路径如何正确选择及配置?  如何在景安服务器上快速搭建个人网站?  如何在景安云服务器上绑定域名并配置虚拟主机?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  如何在万网主机上快速搭建网站?  Android使用GridView实现日历的简单功能  广州美橙建站如何快速搭建多端合一网站?  高端企业智能建站程序:SEO优化与响应式模板定制开发  如何选择适合PHP云建站的开源框架?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。