SQL Server 动态生成分区脚本

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介:

一、前言

前段时间使用表分区比较多,虽然已经写了SQL Server 合并(删除)分区解惑SQL Server 2005 分区模板与实例,但是在实践中一直感觉修改SQL脚本的时间比较多,一直想抽个时间来把分区脚本进行动态化,今天终于付之于行动了。需要说明的一点,下面的脚本并不能满足所有情况,用户可以根据自己的需要进行相应的调整,应该可以满足你的需求的。

在SQL Server 2005中只能通过SQL脚本来创建表分区,而在SQL Server 2008的SSMS中已经提供了操作界面进行表分区,但是也不能把操作生成SQL脚本,所以,下面的SQL的应用场景包括SQL Server 2005、SQL Server 2008。

 

二、分解

下面就是生成分区的脚本了,在执行之前,你需要填写数据库名称、表名、分区表字段、需要的分区数、保存分区文件的路径、分区初始化大小、分区文件的增量、分区边界值;

这里的分区边界值是按照int类型进行增量计算的,比如你想以每100W进行范围分区的话,那你只要设置@FunValue为100W;如果你的分区边界值是其它类型值或者是不等范围的分区,那么你只要修改这个变量为字符串,并对分区函数的生成代码进行相应修改就可以满足你的需求了。

通常情况下,我们会以一个表Id(int),并且是自增作为分区字段,这样就很容易区分历史数据了,而且对分区的操作隔离也是最明显的。

-- 生成分区脚本
DECLARE  @DataBaseName  NVARCHAR( 50) -- 数据库名称
DECLARE  @TableName  NVARCHAR( 50) -- 表名称
DECLARE  @ColumnName  NVARCHAR( 50) -- 字段名称
DECLARE  @PartNumber  INT -- 需要分多少个区
DECLARE  @Location  NVARCHAR( 50) -- 保存分区文件的路径
DECLARE  @Size  NVARCHAR( 50) -- 分区初始化大小
DECLARE  @FileGrowth  NVARCHAR( 50) -- 分区文件增量
DECLARE  @FunValue  INT -- 分区分段值
DECLARE  @i  INT
DECLARE  @PartNumberStr  NVARCHAR( 50)
DECLARE  @sql  NVARCHAR( max)

-- 设置下面变量
SET  @DataBaseName  =  ' MyDataBase '
SET  @TableName  =  ' User '
SET  @ColumnName  =  ' Id '
SET  @PartNumber  =  4
SET  @Location  =  ' E:\DataBase\ '
SET  @Size  =  ' 30MB '
SET  @FileGrowth  =  ' 10% '
SET  @FunValue  =  10000000


-- 1.创建文件组
SET  @i  =  1
PRINT  ' --1.创建文件组 '
WHILE  @i  <=  @PartNumber
BEGIN
     SET  @PartNumberStr  =   RIGHT( ' 0 '  +  CONVERT( NVARCHAR, @i), 2)
     SET  @sql  =  ' ALTER DATABASE [ ' + @DataBaseName  + ' ]
ADD FILEGROUP [FG_
' + @TableName + ' _ ' + @ColumnName + ' _ ' + @PartNumberStr + ' ] '
     PRINT  @sql  +  CHAR( 13)
     SET  @i = @i + 1
END

-- 2.创建文件
SET  @i  =  1
PRINT  CHAR( 13) + ' --2.创建文件 '
WHILE  @i  <=  @PartNumber
BEGIN
     SET  @PartNumberStr  =   RIGHT( ' 0 '  +  CONVERT( NVARCHAR, @i), 2)
     SET  @sql  =  ' ALTER DATABASE [ ' + @DataBaseName  + ' ]
ADD FILE
(NAME = N
'' FG_ ' + @TableName + ' _ ' + @ColumnName + ' _ ' + @PartNumberStr + ' _data '' ,FILENAME = N ''' + @Location + ' FG_ ' + @TableName + ' _ ' + @ColumnName + ' _ ' + @PartNumberStr + ' _data.ndf '' ,SIZE =  ' + @Size + ' , FILEGROWTH =  ' + @FileGrowth + '  )
TO FILEGROUP [FG_
' + @TableName + ' _ ' + @ColumnName + ' _ ' + @PartNumberStr + ' ]; '
     PRINT  @sql  +  CHAR( 13)
     SET  @i = @i + 1
END


-- 3.创建分区函数
PRINT  CHAR( 13) + ' --3.创建分区函数 '
DECLARE  @FunValueStr  NVARCHAR( MAX
SET  @i  =  1
SET  @FunValueStr  =  ''
WHILE  @i  <  @PartNumber
BEGIN
     SET  @FunValueStr  =  @FunValueStr  +  convert( NVARCHAR( 50),( @i * @FunValue))  +  ' , '
     SET  @i = @i + 1
END
SET  @FunValueStr  =  substring( @FunValueStr, 1, len( @FunValueStr) - 1)
SET  @sql  =  ' CREATE PARTITION FUNCTION
Fun_
' + @TableName + ' _ ' + @ColumnName + ' (INT) AS
RANGE RIGHT
FOR VALUES(
' + @FunValueStr + ' ) '
PRINT  @sql  +  CHAR( 13)


-- 4.创建分区方案
PRINT  CHAR( 13) + ' --4.创建分区方案 '
DECLARE  @FileGroupStr  NVARCHAR( MAX
SET  @i  =  1
SET  @FileGroupStr  =  ''
WHILE  @i  <=  @PartNumber
BEGIN
     SET  @PartNumberStr  =   RIGHT( ' 0 '  +  CONVERT( NVARCHAR, @i), 2)
     SET  @FileGroupStr  =  @FileGroupStr  +  ' [FG_ ' + @TableName + ' _ ' + @ColumnName + ' _ ' + @PartNumberStr + ' ], '
     SET  @i = @i + 1
END
SET  @FileGroupStr  =  substring( @FileGroupStr, 1, len( @FileGroupStr) - 1)
SET  @sql  =  ' CREATE PARTITION SCHEME
Sch_
' + @TableName + ' _ ' + @ColumnName + '  AS
PARTITION Fun_
' + @TableName + ' _ ' + @ColumnName + '
TO(
' + @FileGroupStr + ' ) '
PRINT  @sql  +  CHAR( 13)


-- 5.分区函数的记录数
PRINT  CHAR( 13) + ' --5.分区函数的记录数 '
SET  @sql  =  ' SELECT $PARTITION.Fun_ ' + @TableName + ' _ ' + @ColumnName + ' ( ' + @ColumnName + ' ) AS Partition_num,
  MIN(
' + @ColumnName + ' ) AS Min_value,MAX( ' + @ColumnName + ' ) AS Max_value,COUNT(1) AS Record_num
FROM dbo.
' + @TableName + '
GROUP BY $PARTITION.Fun_
' + @TableName + ' _ ' + @ColumnName + ' ( ' + @ColumnName + ' )
ORDER BY $PARTITION.Fun_
' + @TableName + ' _ ' + @ColumnName + ' ( ' + @ColumnName + ' ); '
PRINT  @sql  +  CHAR( 13)

生成的脚本如下:

-- 1.创建文件组
ALTER  DATABASE  [ MyDataBase ]
ADD FILEGROUP  [ FG_User_Id_01 ]

ALTER  DATABASE  [ MyDataBase ]
ADD FILEGROUP  [ FG_User_Id_02 ]

ALTER  DATABASE  [ MyDataBase ]
ADD FILEGROUP  [ FG_User_Id_03 ]

ALTER  DATABASE  [ MyDataBase ]
ADD FILEGROUP  [ FG_User_Id_04 ]


-- 2.创建文件
ALTER  DATABASE  [ MyDataBase ]
ADD  FILE
(NAME  = N ' FG_User_Id_01_data ',FILENAME  = N ' E:\DataBase\FG_User_Id_01_data.ndf ',SIZE  = 30MB, FILEGROWTH  =  10 % )
TO FILEGROUP  [ FG_User_Id_01 ];

ALTER  DATABASE  [ MyDataBase ]
ADD  FILE
(NAME  = N ' FG_User_Id_02_data ',FILENAME  = N ' E:\DataBase\FG_User_Id_02_data.ndf ',SIZE  = 30MB, FILEGROWTH  =  10 % )
TO FILEGROUP  [ FG_User_Id_02 ];

ALTER  DATABASE  [ MyDataBase ]
ADD  FILE
(NAME  = N ' FG_User_Id_03_data ',FILENAME  = N ' E:\DataBase\FG_User_Id_03_data.ndf ',SIZE  = 30MB, FILEGROWTH  =  10 % )
TO FILEGROUP  [ FG_User_Id_03 ];

ALTER  DATABASE  [ MyDataBase ]
ADD  FILE
(NAME  = N ' FG_User_Id_04_data ',FILENAME  = N ' E:\DataBase\FG_User_Id_04_data.ndf ',SIZE  = 30MB, FILEGROWTH  =  10 % )
TO FILEGROUP  [ FG_User_Id_04 ];


-- 3.创建分区函数
CREATE PARTITION  FUNCTION
Fun_User_Id( INTAS
RANGE  RIGHT
FOR  VALUES( 10000000, 20000000, 30000000)


-- 4.创建分区方案
CREATE PARTITION SCHEME
Sch_User_Id  AS
PARTITION Fun_User_Id
TO( [ FG_User_Id_01 ], [ FG_User_Id_02 ], [ FG_User_Id_03 ], [ FG_User_Id_04 ])


-- 5.分区函数的记录数
SELECT $PARTITION.Fun_User_Id(Id)  AS Partition_num,
   MIN(Id)  AS Min_value, MAX(Id)  AS Max_value, COUNT( 1AS Record_num
FROM dbo. User
GROUP  BY $PARTITION.Fun_User_Id(Id)
ORDER  BY $PARTITION.Fun_User_Id(Id);

三、后记

在MSND的SQL Server 2005 中的分区表和索引中同样提供了一个脚本用于生成表分区,和他不同的是:他采用了表来保存文件路径,再使用游标来创建文件而已,其实这只能生成一部分代码,而我的脚本不同之处就是能最大限度的生成常规表分区的常用代码,方便快捷很多。有兴趣的童鞋可以下载:SQL2005PartitioningScripts.exe

上面使用表保存信息的这种想法在后期的数据搬迁(比如需要对一个现有的表进行表分区,这种情况下通常会先建一个分区表,再进行导入现有表的数据)中是有很大的用处的,后面的文章中会讲讲如何进行自动化的数据搬迁,敬请留意。


相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
|
22天前
|
SQL 关系型数据库 MySQL
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
31 0
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
存储 SQL Go
全网最长的sql server巡检脚本分享(1000行)
全网最长的sql server巡检脚本分享(1000行)
54 1
|
3月前
|
SQL 存储 关系型数据库
bat脚本拼写SQL并写文件
【8月更文挑战第7天】bat脚本拼写SQL并写文件
47 5
|
4月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
61 6
|
3月前
|
SQL 存储 Go
SQL Server一键巡检脚本分享
SQL Server一键巡检脚本分享
30 0
|
3月前
|
SQL 监控 安全
在Linux中,如何检测和防止SQL注入和跨站脚本(XSS)攻击?
在Linux中,如何检测和防止SQL注入和跨站脚本(XSS)攻击?
|
3月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
477 0
|
3月前
|
SQL 存储 Oracle
MySQL 项目中 SQL 脚本更新、升级方式,防止多次重复执行
MySQL 项目中 SQL 脚本更新、升级方式,防止多次重复执行
64 0