SQL Server 2008 分区函数和分区表详解

SQL Server 2008 分区函数和分区表详解

2012-10-28 20:06 来源:博客园 作者:zhijianliutang 字号:T|T

[摘要]本文详细介绍SQL Server 2008 分区函数和分区表,包括查询某个分区、归档数据、添加分区、删除分区等内容。

当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的更小。维护任务(例如,重新生成索引或备份表)也可以更快的运行。

我们可以再不通过将表物理放置在多个磁盘驱动器上来拆分表的情况下获取分区。如果将某个表放置在一个物理驱动器上,将相关表放置在另一个驱动器上,则可以提高查询性能,因为当运行涉及表间连接的查询时,多个磁盘头同时读取数据。可以使用SQL Server文件组来指定放置表的磁盘。

对于分区的方式,基本就三种方式:硬件分区、水平分区、垂直分区。相关方案可以参考SQL联机丛书。

这里我们介绍分区表的具体实战方法:

第一步,首先建立我们要使用的数据库,最重要的是建立多个文件组。

我们先新建立四个目录,来组成文件组,一个用来存放主文件的目录:Primary

三个数据文件目录:FG1、FG2、FG3

建立库:

View Row Code

1 create  database  Sales on primary
2 (
3    name=N‘Sales‘,
4    filename=N‘G:\data\Primary\Sales.mdf‘,
5    size=3MB,
6    maxsize=100MB,
7    filegrowth=10%
8 ),
9 filegroup FG1
10 (
11   NAME = N‘File1‘,  
12   FILENAME = N‘G:\data\FG1\File1.ndf‘,  
13   SIZE = 1MB,  
14   MAXSIZE = 100MB,  
15   FILEGROWTH = 10%
16 ),
17 FILEGROUP FG2  
18 (  
19   NAME = N‘File2‘,  
20   FILENAME = N‘G:\data\FG2\File2.ndf‘,  
21   SIZE = 1MB,  
22   MAXSIZE = 100MB,
23   FILEGROWTH = 10%  
24 ),
25 FILEGROUP FG3  
26 (  
27   NAME = N‘File3‘,  
28   FILENAME = N‘G:\data\FG3\File3.ndf‘,  
29   SIZE = 1MB,  
30   MAXSIZE = 100MB,  
31   FILEGROWTH = 10%  
32 )  
33 LOG ON  
34 (  
35   NAME = N‘Sales_Log‘,  
36   FILENAME = N‘G:\data\Primary\Sales_Log.ldf‘,  
37   SIZE = 1MB,  
38   MAXSIZE = 100MB,  
39   FILEGROWTH = 10%
40 )
41 GO

第二步:建立分区函数,目的是用来规范不同数据存放到不同目录的标准,简单讲就是如何分区。

View Row Code

1 USE Sales  
2 GO
3 CREATE PARTITION FUNCTION pf_OrderDate (datetime)  
4 AS RANGE RIGHT  
5 FOR VALUES (‘2003/01/01‘, ‘2004/01/01‘)
6 GO

我们创建了一个用于数据类型为datetime的分区函数,按照时间段来划分。

文件组 分区 取值范围 FG1 1 (过去某年, 2003/01/01) FG2 2 [2003/01/01, 2004/01/01) FG3 3 [2004/01/01,未来某年)

第三步:创建分区方案,关联到分区函数。目的就是我们将已经建立好的分区函数组织成一套方案,简单点将就是我们在哪里对数据进行分区。

View Row Code

1 Use Sales
2 go
3 create  partition  scheme ps_OrderDate
4 as partition  pf_OrderDate
5 to(FG2,FG2,FG3)
6 go

很简单,就是将第二步建立的分区函数应用已经建立的分区组中。

第四步:创建分区表。创建表并将其绑定到分区方案上。我们首先建立两个表,一张原始表另一张用来归档数据,保存归档数据。

View Row Code

1 Use Sales
2 go
3 create table Orders
4 (
5    OrderID int identity(10000,1),
6    OrderDate datetime  not null,
7    CustomerID int not null,
8    constraint  PK_Orders primary key(OrderID,OrderDate)
9 )
10 on ps_OrderDate(OrderDate)
11 go
12 create table OrdersHistory
13 (
14    OrderID int identity(10000,1),
15    OrderDate datetime  not null,
16    CustomerID int not null,
17    constraint  PK_OrdersHistory primary key(OrderID,OrderDate)
18 )
19 on ps_OrderDate(OrderDate)
20 go

到这里,通过上面的四步我们已经完整的搭建好了一个带有分区表的库,我们来插入一些数据,来测试下我们建立是否好用。

首先,因为是用2003年1月1号作为区分点的,我们先向数据表中写入2002年的规范数据:

View Row Code

1 USE Sales  
2 GO  
3 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2002/6/25‘, 1000)  
4 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2002/8/13‘, 1000)  
5 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2002/8/25‘, 1000)  
6 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2002/9/23‘, 1000)
7 GO

同样我们写入2003年四条数据:

View Row Code

1 USE Sales  
2 GO
3 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2003/6/25‘, 1000)
4 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2003/8/13‘, 1000)
5 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2003/8/25‘, 1000)
6 INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES (‘2003/9/23‘, 1000)  
7 GO

我们来查看这些数据是否完整录入:

因为OrdersHistory表我们还没有归档数据,所以为空。

我们来分条件查询下:

1、查询某个分区

这里我们要用到$partition函数。这个函数在联机丛书中是这样解释的:

用法: 为任何指定的分区函数返回分区号,一组分区列值将映射到该分区号中。 语法: [ database_name. ] $PARTITION.partition_function_name(expression) 参数: database_name
包含分区函数的数据库的名称。 partition_function_name
对其应用一组分区列值的任何现有分区函数的名称。 expression
其数据类型必须匹配或可隐式转换为其对应分区列数据类型的表达式。expression 也可以是当前参与 partition_function_name 的分区列的名称。 返回类型: int 备注: $PARTITION 返回从 1 到分区函数的分区数之间的 int 值。 $PARTITION 将针对任何有效值返回分区号,无论此值当前是否存在于使用分区函数的分区表或索引中。

我们来查询分区表Order的第一个分区,代码如下:

可以看到我们查询出来的数据全部为2002年的,也就是说在第一分区中我们存入的数据都是小于2003年,按照此推断2003年的数据,就应该存在第二分区中:

结果如我们所料,我们可以按照这个分区进行分组来查看各个分区的数据行多少,代码如下:

View Row Code

1 select $partition.pf_OrderDate(OrderDate) as Patition,COUNT(*) countRow from dbo.Orders
2 group by $partition.pf_OrderDate(OrderDate)

还可以通过$Partition函数获得一组分区标识列值的分区号,例如获得2002属于哪个分区,代码如下:

2、归档数据

假如现在是2003年年初,那么我们就可以把2002您所有的交易记录归档到我们刚才建立的历史订单表HistroryOrder中。代码如下:

View Row Code

1 Use Sales
2 go
3 alter table orders switch partition 1 to ordersHistory partition 1
4 go

现在我们再重新查看这两张表的数据:

这时候Orders表只剩下2003年的数据,而OdersHistory表中包含了2002年的数据。

简单点讲就是把第一区的数据导入到另一张分区表的第一区中。

当然如果到了2004年年初,我们就可以归档2003年的所有交易数据。

View Row Code

1 Use Sales
2 go
3 alter table orders switch partition 2 to ordersHistory partition 2
4 go

这里需要注意的是我们按照区进行数据修改的时候,必须是同一种分区函数下的分区表进行操作,并且分区结构相对应,如果不这样会报错,例如:

3、添加分区

当我们需要新添加分区的时候,我们需要修改分区方案,比如现在我们到了2005年年初,我们需要为2005年的交易记录准备分区,就需要添加分区:

View Row Code

1 USE [master]
2 GO
3 ALTER DATABASE [Sales] ADD FILEGROUP [FG4]
4 GO
5 ALTER DATABASE [Sales] ADD FILE ( NAME = N‘File4‘, FILENAME = N‘G:\data\FG4\File4.ndf‘ , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [FG4]
6 GO

我们新建立了一个文件组,然我们同样按照上面的方法,进行修改分区函数和方案:

View Row Code

1 use Sales
2 go
3 alter partition scheme ps_OrderDate  next used [FG4]
4 alter partition function  pf_OrderDate() split range(‘2005/01/01‘)
5 go

我们这里用alter partition Scheme ps_OrderDate Next Used FG4用来指定新分区的数据在那个文件。这里Next Used FG4指定的就是我们刚才新建立的第四个文件组。当然我们可以放在原来已经建立的文件组,为了防治数据混乱存放我们大部分是新建立文件组。

alter partition function pf_OrderDate() split range(‘2005/01/01‘)代表我么创建一个新分区,而这里split range是创建新分区的关键语法。

至此,我们就有了四个分区,此时的区间如下:

文件组 分区 取值范围 FG1 1 (过去某年, 2003/01/01) FG2 2 [2003/01/01, 2004/01/01) FG3 3 [2004/01/01,2005/01/01] FG4 4 [2004/01/01,未来某年)

4、删除分区

删除分区又称合并分区,简单讲就是两个分区的数据进行合并,比如我们想合并2002年的分区和2003年的分区到一个分区,我们可以用如下的代码:

View Row Code

1 use Sales
2 go
3 alter partition function  pf_OrderDate() merge range(‘2003/01/01‘)
4 go

也就是将2003年这个分区点去掉,里面分区里面的数据会自动合并到一起。

执行完上面的代码,此时分区区间如下:

文件组 分区 取值范围 Fg2 1 [过去某年, 2004/01/01) Fg3 2 [2004/01/01, 2005/01/01) Fg2 3 [2005/01/01, 未来某年)

合并2002和2003年的数据到2003年之后,我们执行如下代码:

View Row Code

1 SELECT Sales.$PARTITION.pf_OrderDate(‘2003‘)

你会发现返回的结果是1。而原来返回的是2,原因是2002年以前数据所在的那个分区合并到了2003年这个分区中了。

此时我们执行下面代码:

View Row Code

1 SELECT *
2 FROM dbo.OrdersHistory  
3 WHERE $PARTITION.pf_OrderDate(OrderDate) = 2

结果一行数据都没返回,事实就这样,因为OrderHistroy表中只存储了2002和2003年的历史数据,在没有合并分区之前,执行上面的代码肯定会查询出2003年的数据,但是合并了分区之后,上面代码实际查询的是第二个分区中2004年的数据。

不过我们改成如下代码:

View Row Code

1 SELECT *
2 FROM dbo.OrdersHistory  
3 WHERE $PARTITION.pf_OrderDate(OrderDate) = 1

便会查询出8行数据,包括2002年和2003年的数据,因为合并分区后2002年和2003年的数据都成了第1分区的数据了。

5、查看元数据

我们可以通过三个系统视图来查看我们的分区函数,分区方案,边界值点等。

View Row Code

1 select * from sys.partition_functions  
2 select * from sys.partition_range_values
3 select * from sys.partition_schemes
时间: 2024-08-12 04:17:41

SQL Server 2008 分区函数和分区表详解的相关文章

深入浅出SQL Server 2008 分区函数和分区表

原文:深入浅出SQL Server 2008 分区函数和分区表 当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的更小.维护任务(例如,重新生成索引或备份表)也可以更快的运行. 我们可以再不通过将表物理放置在多个磁盘驱动器上来拆分表的情况下获取分区.如果将某个表放置在一个物理驱动器上,将相关表放置在另一个驱动器上,则可以提高查询性能,因为当运行涉及表间连接的查询时,多个磁盘头同时读取数据.可以使用SQL Ser

SQL Server 2008 分区函数和分区表

当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的更小.维护任务(例如,重新生成索引或备份表)也可以更快的运行. 我们可以再不通过将表物理放置在多个磁盘驱动器上来拆分表的情况下获取分区.如果将某个表放置在一个物理驱动器上,将相关表放置在另一个驱动器上,则可以提高查询性能,因为当运行涉及表间连接的查询时,多个磁盘头同时读取数据.可以使用SQL Server文件组来指定放置表的磁盘. 对于分区的方式,基本就三种方式

SQL Server 2008 CDC增量变更捕获详解

1 背景: 随着公司业务的成长,数据量也随之的不断增长.随之而来的问题是在做ETL的时候,时间花费也越来越长.为了节省时间开销,我们只想要更新最新的数据,不想要把公司历年所有的数据都进行处理.这种情况就被称为变更数据捕获(Change Data Capture,又名CDC).在SQLServer2008之前,对数据变更的捕获通常使用触发器把DML操作中的INSERT/UPDATE/DELETE数据记录下来,但是触发器的维护比较困难:时间戳严重依赖于数据库的设计,而且必须在业务代码中对时间字段进行

奇怪的 sql server 2008 Power 函数

bigint 的 数据范围是  从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据 但是 , 如果这么写 print CAST(POWER(3, 20) AS BIGINT) 会报这个错误 Msg 232, Level 16, State 3, Line 1 Arithmetic overflow error for type int, value = 3486784401.000000. 尽管 34867844

Microsoft SQL Server中的事务与并发详解

本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一组语句要么全部成功,对数据库中的某些数据成功修改; 要么全部不成功,数据库中的数据还原到这些语句执行之前的样子. 比如网上订火车票,要么你定票成功,余票显示就减一张; 要么你定票失败获取取消订票,余票的数量还是那么多.不允许出现你订票成功了,余票没有减少或者你取消订票了,余票显示却少了一张的这种情况

SQL Server 默认跟踪(Trace)捕获事件详解

SQL Server 默认跟踪 -- 捕获事件详解 哪些具体事件默认跟踪文件能够捕获到? --returns full list of events SELECT * FROM sys.trace_events --returns a full list of categories SELECT * FROM sys.trace_categories --returns a full list of subclass values SELECT * FROM sys.trace_subclass

SQL Server日期时间格式转换字符串详解

1.日期时间转字符串 Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006  10:57AMSelect CONVERT(varchar(100), GETDATE(), 1): 05/16/06Select  CONVERT(varchar(100), GETDATE(), 2): 06.05.16Select CONVERT(varchar(100),  GETDATE(), 3): 16/05/06Select CONVERT(var

SQL Server 2012 Enterprise Edition安装过程详解(包含每一步怎么设置及原因)

一.启动安装程序,点击“安装”选项卡,选择“全新SQL Server独立安装或向现有安装添加功能”.(首次安装数据库系统或向现有数据库系统添加功能,均选择此选项) 二.随后,安装程序进行“安装程序支持规则”的检测,来分析要成功安装SQL Server 2012 Enterprise Edition的前提条件是否都满足.如果存在某一个或多个条件(规则)没有通过,安装过程将无法进行,必须更正失败项才能继续.如果都满足(所有规则的状态为已通过)点击“确定”. 三.输入产品秘钥并点击“下一步”: 四.勾

SQL Server 连接字符串和身份验证详解

SQL Server .NET Data Provider 连接字符串包含一个由一些属性名/值对组成的集合.每一个属性/值对都由分号隔开.          PropertyName1=Value1;PropertyName2=Value2;PropertyName3=Value3;.....同样,连接字符串必须包含SQL Server实例名称:          Data Source=ServerName;          使用本地的SQL Server(localhost),如果想要使用