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

时间:2022-03-18 03:55:26
      当数据库表中数据量能够被预测到将会非常大,或者已经拥有庞大的数据时,我们应该选择分表或者分区(即使用多个数据库)来解决数据访问时的性能问题。
为什么要分区分表呢?因为分区分表有如下几个有点:
1.改善查询性能,对分区对象的查询可以仅搜索自己关系的分区,提高检索速度。
2.增强可用性,如果表的某个分区出现故障,表在其他分区的数据仍然可用。
3.维护方面,如果表的某个分区出现故障,需要修复数据,只修复该分区即可。
4.均衡I/O,可以把不同的分区映射到磁盘以平衡I/O,改善整个性能。
好了,废话不多说了,首先我们需要准备以下工作:
1.SQL Server 2008 下载地址
http://sqlserver.dlservice.microsoft.com/dl/download/B/8/0/B808AF59-7619-4A71-A447-F597DE74AC44/SQLFULL_CHS.iso?lcid=2052 
对了iso文件是一种光盘映像文件,对于win8以下版本的操作系统需要安装第三方工具才能打开,这里推荐使用对个人用户免费的Daemon Tool Lite。

Daemon Tool Lite 下载地址:http://www.cr173.com/soft/28615.html

以下为具体操作方法:

(1)、下载“工具/原料”处的虚拟光驱软件安装程序并运行,语言选择中文,点击"下一步"
(2)、点击“我同意” 
 (3)、选择“免费许可”免费使用该软件 
(4)、去掉其余选项前的对勾,只保留“文件关联”一项,点击“下一步” 
(5)、是否允许发送统计信息都可以,点击“下一步” 
(6)、选择安装目录,点击“安装”开始安装 
 (7)、等待几分钟后安装完成。去掉图中“运行Daemon Tools Lite”的对勾,点击“关闭” 
(8)、打开资源管理器,在需要打开的iso文件上双击。稍候屏幕会显示“正在载入映像...” 
(9)、此时打开“计算机”查看多出来的虚拟光驱(如图所示),可以像普通光盘一样操作了 
接下来就可以安装数据库了
2.安装方法图解 http://jingyan.baidu.com/article/86fae3469e6c4b3c48121a76.html
3.密钥
Enterprise: JD8Y6-HQG69-P9H84-XDTPG-34MBB
安装完毕之后,接下来我们可以实现分区分表了
第一步,首先建立我们要使用的数据库,最重要的是建立多个文件组。 

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

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

建立库: 
create  database  Sales on primary (    name=N'Sales',    filename=N'G:\data\Primary\Sales.mdf',    size=3MB,    maxsize=100MB,    filegrowth=10% ), filegroup FG1 (   NAME = N'File1',      FILENAME = N'G:\data\FG1\File1.ndf',      SIZE = 1MB,      MAXSIZE = 100MB,      FILEGROWTH = 10%  ), FILEGROUP FG2    (      NAME = N'File2',      FILENAME = N'G:\data\FG2\File2.ndf',      SIZE = 1MB,      MAXSIZE = 100MB,   FILEGROWTH = 10%    ), FILEGROUP FG3    (      NAME = N'File3',      FILENAME = N'G:\data\FG3\File3.ndf',      SIZE = 1MB,      MAXSIZE = 100MB,      FILEGROWTH = 10%    )    LOG ON    (      NAME = N'Sales_Log',      FILENAME = N'G:\data\Primary\Sales_Log.ldf',      SIZE = 1MB,      MAXSIZE = 100MB,      FILEGROWTH = 10% ) GO 
第二步:建立分区函数,目的是用来规范不同数据存放到不同目录的标准,简单讲就是如何分区。 
USE Sales   
GO
CREATE PARTITION FUNCTION pf_OrderDate (datetime)   
AS RANGE RIGHT   
FOR VALUES ('2003/01/01', '2004/01/01') 
GO

我们创建了一个用于数据类型为datetime的分区函数,按照时间段来划分
文件组 分区    取值范围
FG1    1        (过去某年, 2003/01/01)
FG2    2       [2003/01/01, 2004/01/01)
FG3    3        [2004/01/01,未来某年)

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

Use Sales
go
create  partition  scheme ps_OrderDate
as partition  pf_OrderDate
to(FG2,FG2,FG3)
go
很简单,就是将第二步建立的分区函数应用已经建立的分区组中。
第四步:创建分区表。创建表并将其绑定到分区方案上。我们首先建立两个表,一张原始表另一张用来归档数据,保存归档数据。
Use Sales go create table Orders (    OrderID int identity(10000,1),    OrderDate datetime  not null,    CustomerID int not null,    constraint  PK_Orders primary key(OrderID,OrderDate) ) on ps_OrderDate(OrderDate) go create table OrdersHistory (    OrderID int identity(10000,1),    OrderDate datetime  not null,    CustomerID int not null,    constraint  PK_OrdersHistory primary key(OrderID,OrderDate) ) on ps_OrderDate(OrderDate) go 
 

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

 3、添加分区

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

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

USE Sales    GO    INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/6/25', 1000)    INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/8/13', 1000)    INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/8/25', 1000)    INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2002/9/23', 1000) GO

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

USE Sales    GO INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/6/25', 1000) INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/8/13', 1000) INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/8/25', 1000) INSERT INTO dbo.Orders (OrderDate, CustomerID) VALUES ('2003/9/23', 1000)    GO

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

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

因为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的第一个分区,代码如下:

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

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

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

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

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

2、归档数据

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

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

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

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

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

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

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

 3、添加分区

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

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

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

use Sales go alter partition scheme ps_OrderDate next used [FG4] alter partition function pf_OrderDate() split range('2005/01/01') 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年的分区到一个分区,我们可以用如下的代码:

use Sales go alter partition function pf_OrderDate() merge range('2003/01/01') go

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

执行完上面的代码,此时分区区间如下:
文件组 分区      取值范围
Fg2     1        [过去某年, 2004/01/01)
Fg3     2        [2004/01/01, 2005/01/01)
Fg2     3        [2005/01/01, 未来某年)

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

SELECT Sales.$PARTITION.pf_OrderDate('2003')

你会发现返回的结果是1。而原来返回的是2,原因是2002年以前数据所在的那个分区合并到了2003年这个分区中了。
此时我们执行下面代码:

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

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

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

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

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

select * from sys.partition_functions select * from sys.partition_range_values select * from sys.partition_schemes
完毕。