Sql Server系列:分区表操作
1. 分区表简介
分区表在逻辑上是一个表,而物理上是多个表。从用户角度来看,分区表和普通表是一样的。使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性。
分区表是把数据按设定的标准划分成区域存储在不同的文件组中,使用分区可以快速而有效管理和访问数据子集。
1.1> 适合做分区表的情况
◊ 数据库中某个表的数据很多,在查询数据时会明显感觉到速度很慢,这个时候需要考虑分区表;
◊ 数据是分段的,如以年份为分隔的数据,对于当年的数据经常进行增删改查操作,而对于往年的数据几乎不做操作或只做查询操作,这种情况可以使用分区表。对数据的操作如果只涉及一部分数据而不是全部数据的情况可以考虑分区表,如果一张表的数据经常使用且不管年份之类的因素经常对其增删改查操作则最好不要分区。
1.2> 分区表的优点
◊ 分区表可以从物理上将一个大表分成几个小表,但是从逻辑上来看还是一个大表。
◊ 对于具有多个CPU的系统,分区可以对表的操作通过并行的方式进行,可以提升访问性能。
2. 创建分区表步骤
创建分区表的步骤分为5步:
(1)创建数据库文件组
(2)创建数据库文件
(3)创建分区函数
(4)创建分区方案
(5)创建分区表
2.1> 创建数据库文件组
新建示例数据库Northwind,创建数据库文件组和文件,添加文件组。
2.2> 创建数据库文件
创建数据文件,并为数据文件分配文件组。
完成创建后的数据库文件信息
通过SQL Server Profiler可以看到具体的创建数据库的脚本如下:
CREATE DATABASE [Northwind]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'Northwind', FILENAME = N'F:\Database\Northwind\Northwind.mdf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2010]
( NAME = N'Northwind_Data_2010', FILENAME = N'F:\Database\Northwind\Northwind_Data_2010.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2011]
( NAME = N'Northwind_Data_2011', FILENAME = N'F:\Database\Northwind\Northwind_Data_2011.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2012]
( NAME = N'Northwind_Data_2012', FILENAME = N'F:\Database\Northwind\Northwind_Data_2012.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2013]
( NAME = N'Northwind_Data_2013', FILENAME = N'F:\Database\Northwind\Northwind_Data_2013.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ),
FILEGROUP [SECTION2014]
( NAME = N'Northwind_Data_2014', FILENAME = N'F:\Database\Northwind\Northwind_Data_2014.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'Northwind_log', FILENAME = N'F:\Database\Northwind\Northwind_log.ldf' , SIZE = 2048KB , FILEGROWTH = 10%)
查看数据库文件组SQL语句:
2.3> 创建分区函数
创建分区函数Transact-SQL语法:
CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )
AS RANGE [ LEFT | RIGHT ]
FOR VALUES ( [ boundary_value [ ,...n ] ] )
[ ; ]
参数:
partition_function_name:分区函数的名称。 分区函数名称在数据库内必须唯一,并且符合标识符的规则。
input_parameter_type:用于分区的列的数据类型。 当用作分区列时,除 text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、别名数据类型或 CLR 用户定义数据类型外,所有数据类型均有效。
boundary_value:为使用 partition_function_name 的已分区表或索引的每个分区指定边界值。 如果 boundary_value 为空,则分区函数使 partition_function_name 将整个表或索引映射到单个分区。 只能使用 CREATE TABLE 或 CREATE INDEX 语句中指定的一个分区列。
LEFT | RIGHT 指定当间隔值由 数据库引擎 按升序从左到右排序时,boundary_value [ ,...n ] 属于每个边界值间隔的哪一侧(左侧还是右侧)。 如果未指定,则默认值为 LEFT。
示例:创建将用于Order表的分区函数
CREATE PARTITION FUNCTION Function_DateTime ( DATETIME )
AS RANGE RIGHT
FOR VALUES('2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01')
完成创建分区函数之后,可以通过以下SQL语句查看已创建的分区函数情况。
SELECT * FROM sys.partition_functions
2.4> 创建分区方案
分区方案的作用是将分区函数生成的分区映射到文件组中去,分区方案是让SQL Server将已分区的数据放在哪个文件组中。
在当前数据库中创建一个将已分区表或已分区索引的分区映射到文件组的方案。 已分区表或已分区索引的分区的个数和域在分区函数中确定。 必须首先在 CREATE PARTITION FUNCTION 语句中创建分区函数,然后才能创建分区方案。
创建分区方案的Transact-SQL语法:
CREATE PARTITION SCHEME partition_scheme_name
AS PARTITION partition_function_name
[ ALL ] TO ( { file_group_name | [ PRIMARY ] } [ ,...n ] )
[ ; ]
参数:
partition_scheme_name:分区方案的名称。 分区方案名称在数据库中必须是唯一的,并且符合标识符规则。
partition_function_name:使用分区方案的分区函数的名称。 分区函数所创建的分区将映射到在分区方案中指定的文件组。 partition_function_name 必须已经存在于数据库中。 单个分区不能同时包含 FILESTREAM 和非 FILESTREAM 文件组。
ALL:指定所有分区都映射到在 file_group_name 中提供的文件组,或映射到主文件组(如果指定了 [PRIMARY]。 如果指定了 ALL,则只能指定一个 file_group_name。
file_group_name | [ PRIMARY ] [ ,...n]:指定用来持有由 partition_function_name 指定的分区的文件组的名称。 file_group_name 必须已经存在于数据库中。
如果指定了 [PRIMARY],则分区将存储于主文件组中。 如果指定了 ALL,则只能指定一个 file_group_name。 分区分配到文件组的顺序是从分区 1 开始,按文件组在 [,...n] 中列出的顺序进行分配。 在 [,...n] 中,可以多次指定同一个 file_group_name。 如果 n 不足以拥有在 partition_function_name 中指定的分区数,则 CREATE PARTITION SCHEME 将失败,并返回错误。
如果 partition_function_name 生成的分区数少于文件组数,则第一个未分配的文件组将标记为 NEXT USED,并且出现显示命名 NEXT USED 文件组的信息。 如果指定了 ALL,则单独的 file_group_name 将为该 partition_function_name 保持它的 NEXT USED 属性。 如果在 ALTER PARTITION FUNCTION 语句中创建了一个分区,则 NEXT USED 文件组将再接收一个分区。 若要再创建一个未分配的文件组来拥有新的分区,请使用 ALTER PARTITION SCHEME。
在 file_group_name[ 1,...n] 中指定主文件组时,必须像在 [PRIMARY] 中那样分隔 PRIMARY,因为它是关键字。
示例:创建将用于Order表的分区方案
CREATE PARTITION SCHEME Scheme_DateTime
AS PARTITION Function_DateTime
TO ( SECTION2010, SECTION2011, SECTION2012, SECTION2013, SECTION2014 )
分区函数和分区方案创建之后,可以在数据库的【存储】中查看:
通过可以通过以下SQL语句查看已创建的分区方案:
SELECT * FROM sys.partition_schemes
2.5> 创建分区表
CREATE TABLE [Order]
(
OrderID INT IDENTITY(1,1) NOT NULL,
UserID INT NOT NULL,
TotalAmount DECIMAL(18,2) NULL,
OrderDate DATETIME NOT NULL
) ON Scheme_DateTime ( OrderDate )
这里需要注意分区表不能再创建聚集索引,因为聚集索引可以将记录在物理上顺序存储,而分区表是将数据存储在不同的表中,这两个概念是冲突的,所以在创建分区表时不能再创建聚集索引。
完成Order表创建之后,查看表的属性,可以看到Order表已经是分区表。
3. 操作分区表
3.1> Insert数据
USE [Northwind]
GO INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (1 ,10.00 ,'2009-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (1 ,20.50 ,'2009-12-31');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (2 ,40.00 ,'2010-01-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (3 ,40.00 ,'2010-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (4 ,50.00 ,'2011-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (5 ,60.00 ,'2012-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (5 ,60.00 ,'2012-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (6 ,70.00 ,'2013-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (10 ,90.00 ,'2014-10-20');
INSERT INTO [dbo].[Order] ([UserID],[TotalAmount] ,[OrderDate]) VALUES (9 ,100.00 ,'2015-10-20');
GO
3.2> 查询数据所在物理分区表
在分区表中使用一般的SELECT语句无法知道数据是分别存放在哪几个不同的物理表中,若要知道数据分别存放的物理表,可以使用$PARTITION函数,该函数可以调用分区函数并返回数据所在物理分区的编号。
$PARTITION的语法:$PARTITION.分区函数名(表达式)
SELECT $PARTITION.Function_DateTime('2010-01-01')
查询结果分区函数返回为1,说明2010-01-01的数据会存放在第1个物理分区表中。
使用$PARTITION函数可以具体知道每个物理分区表中存放了哪些记录。
查看物理分区表中存放的记录:
SELECT * FROM [Order] WHERE $PARTITION.Function_DateTime(OrderDate) = 1
SELECT $PARTITION.Function_DateTime(OrderDate) AS 分区编号, COUNT(1) AS 记录数
FROM [Order]
GROUP BY $PARTITION.Function_DateTime(OrderDate)
3.3> 修改分区表数据
UPDATE dbo.[Order] SET OrderDate='2015-01-01' WHERE OrderID =
4. 将普通表转换为分区表
一般的普通表都是在主键上建聚集索引,记录的物理保存位置由主键决定。
示例:创建一个Product普通表
CREATE TABLE Product
(
ProductID INT IDENTITY(1,1) NOT NULL,
ProductName VARCHAR(100) NOT NULL,
UnitPrice DECIMAL(18,2) NULL,
CreateDate DATETIME NOT NULL,
CONSTRAINT PK_Product PRIMARY KEY CLUSTERED (ProductID)
)
USE [Northwind]
GO INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to SQL' ,10 ,'2012-01-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to XML' ,10 ,'2012-12-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to Object' ,10 ,'2013-02-01');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to ADO.NET' ,10 ,'2014-01-02');
INSERT INTO [dbo].[Product] ([ProductName],[UnitPrice],[CreateDate]) VALUES ('LINQ to Entity' ,10 ,'2015-01-01'); GO
查看表Product的属性:
查看表Product的索引,可以看到PK_Product为聚集索引。
将普通表转换为分区表的操作是先在普通表上删除聚集索引,在创建一个新的聚集索引,在该聚集索引中使用分区方案。
在SQL Server中,主键字段上默认创建聚集索引,删除主键的聚集索引。
ALTER TABLE Product DROP CONSTRAINT PK_Product
重新创建主键非聚集索引
ALTER TABLE Product ADD CONSTRAINT PK_Product PRIMARY KEY NONCLUSTERED (ProductID ASC)
重新创建后的主键:
创建使用分区方案的聚集索引:
CREATE CLUSTERED INDEX IX_CreateDate ON Product ( CreateDate )
ON Scheme_DateTime ( CreateDate )
调整后的Product表属性:
调整后Product表记录的物理保存情况:
5. 删除(合并)一个分区表
删除2012-01-01的分区,修改分区函数:
ALTER PARTITION FUNCTION Function_DateTime() MERGE RANGE ('2012-01-01')
在修改了分区函数之后,与之关联的分区方案也将同时自动调整。在执行了上面合并分区的函数之后,查看分区方案的Create脚本。
CREATE PARTITION SCHEME [Scheme_DateTime] AS PARTITION [Function_DateTime] TO ([SECTION2010], [SECTION2011], [SECTION2013], [SECTION2014])
合并分区之后,被合并的分区记录也将被重新分配物理保存位置。
6. 添加分区
分区方案中指定的文件组个数比分区函数中指定的边界数大1,为分区方案指定一个可用的文件组时,该分区方案并没有立刻使用这个文件组,只是将文件组先备用着,等修改了分区函数之后分区方案才会使用这个文件组。如果分区函数没有更改,分区方案中的文件组个数也不会更改。
添加分区所需要使用到的文件组可以使用之前合并分区之后没有再使用的SECTION2012,也可以新建文件组。
ALTER DATABASE [Northwind] ADD FILEGROUP [SECTION2015]
ALTER DATABASE [Northwind] ADD FILE
(
NAME = N'Northwind_Data_2015',
FILENAME = N'F:\Database\Northwind\Northwind_Data_2015.ndf' ,
SIZE = 5120KB ,
FILEGROWTH = 1024KB
) TO FILEGROUP [SECTION2015]
为分区方案指定一个可用的文件组:
ALTER PARTITION SCHEME Scheme_DateTime NEXT USED [SECTION2015]
修改分区函数,添加分区:
ALTER PARTITION FUNCTION Function_DateTime() SPLIT RANGE('2015-01-01')
查看添加分区后的数据物理存储:
Sql Server系列:分区表操作的更多相关文章
- SQL Server 系列文章快速导航(SWF版)
一.前言 在博客园写博客不自不觉已经有5个年头了,一开始只是为了记录工作中遇到的问题和解决办法,后来写的文章不自不觉的侧重在SQL Server方面的技术文章,在2014年1月终于鼓起勇气申请了微软S ...
- Sql Server系列:触发器
触发器的一些常见用途: ◊ 强制参照完整性 ◊ 常见审计跟踪(Audit Trails):这意味着写出的记录不仅跟踪大多数当前的数据,还包括对每个记录进行实际修改的历史数据. ◊ 创建与CHECK约束 ...
- Sql Server 函数的操作实例!(执行多条语句,返回Select查询后的临时表)
Sql Server 函数的操作实例!(执行多条语句,返回Select查询后的临时表) SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ==== ...
- Sql Server 函数的操作实例!(返回一条Select语句查询后的临时表)
Sql Server 函数的操作实例!(返回一条Select语句查询后的临时表) SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUN ...
- SQL Server系列文章目录
SQL Server系列文章目录SQL Server系列文章目录SQL Server系列文章目录SQL Server系列文章目录
- SQL Server 2005 分区表实践——分区切换
本文演示了 SQL Server 2005 分区表分区切换的三种形式: 1. 切换分区表的一个分区到普通数据表中:Partition to Table: 2. 切换普通表数据到分区表的一个分区中:Ta ...
- SQL SERVER: 合并相关操作(Union,Except,Intersect)
SQL SERVER: 合并相关操作(Union,Except,Intersect) use tempdb create table tempTable1 (id int primary key id ...
- SQL Server 多库操作 库名.dbo.表名 出错的问题!
SQL Server 多库操作 库名.dbo.表名 出错的问题! 数据库名不要用数字开头. 例如:343934.dbo.user 这就会出错.md a343934.dbo.user 就没问题!! 记住 ...
- Sql Server系列:数据表操作
表是用来存储数据和操作数据的逻辑结构,用来组织和存储数据,关系数据库中的所有数据都表现为表的形式,数据表由行和列组成.SQL Server中的数据表分为临时表和永久表,临时表存储在tempdb系统数据 ...
随机推荐
- Android 获取meta-data中的数据
在 Android 的 Mainfest 清单文件中,Application,Activity,Recriver,Service 的节点中都有这个的存在.很多时候我们可以通过 meta-data 来配 ...
- 探索ASP.NET MVC5系列之~~~2.视图篇(上)---包含XSS防御和异步分部视图的处理
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- Matlab 高脚杯模型切片
前言:此文为去年我替人做的一个课题,觉得比较简洁,图形也比较美观,因此放在博文里 数据源我放到了百度云盘高脚杯数据源 有兴趣的可以下载数据,跑程序试一下.也可以单独看看代码,看下实现过程. 主函数 % ...
- C#日志
参考页面: http://www.yuanjiaocheng.net/Entity/first.html http://www.yuanjiaocheng.net/Entity/jieshao.htm ...
- [WPF] Wait for a moment.
一.控件介绍 在 WPF 中使用的等待控件,控件包括三种,普通的等待信息提示(WaitTip),进度条提示(WaitProgress),以及主程序覆盖的模拟时钟等待窗口(WaitClock),具体效果 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- BPM任务管理解决方案分享
一.方案概述任务是企业管理者很多意志的直接体现,对于非常规性事务较多的企业,经常存在各类公司下达的各种任务跟进难.监控难等问题,任务不是完成效果不理解,就是时间超期,甚至很多公司管理层下达的任务都不了 ...
- Android中使用ViewFlipper实现屏幕页面切换(关于坐标轴的问题已补充更改)
屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.如 ...
- ios 类似微信红点显示功能
设计思路:给UIView增加一个分类 所有的视图都可以根据需要来进行红点显示 #import <UIKit/UIKit.h> @interface UIView (CHRRedDot) @ ...
- 使用Hudson搭建自动构建服务器
环境: ubuntu1404_x64 说明: 使用hudson和git搭建自动构建服务器的简单示例 安装hudson及相关插件 安装hudson 安装命令如下: sudo sh -c "ec ...