BIWORK 分区表阅读与实践笔记

/***************************************************************

BIWORK 分区表阅读与实践笔记

Note: 示例中使用到了SQL Server 2000的 Demo Database, 可以从此链接中下载 

http://www.microsoft.com/en-us/download/confirmation.aspx?id=23654

在检查删除Partition Function 以及Partition Scheme 时,要注意

Partition Scheme 引用了Partition Function, 所有需要先删除

Partition Scheme. 同理,引用了Partition Scheme 的表应该先删除掉.

引用关系: TABLE -> PARTITION SCHEME -> PARTITION FUNCTION

***************************************************************/

IF OBJECT_ID('dbo.Orders')IS NOT NULL

DROP TABLE Orders

GO

IF EXISTS (SELECT * FROM sys.partition_schemes WHERE name = 'PS_Orders')

DROP PARTITION SCHEME PS_Orders

GO

IF EXISTS (SELECT * FROM sys.partition_functions WHERE name = 'PF_Orders_OrderDateRange')

DROP PARTITION FUNCTION PF_Orders_OrderDateRange

GO

/***************************************************************

1. 如果在不需要对数据库进行物理分组的情况下,比如分区表还是享用同

一个文件组,那么应该可以从创建分区函数开始

*** 创建分区函数

*** 确定分区键列的类型(DATETIME)以及分区的边界值:

   (''1997-01-01','1998-01-01','1999-01-01'')

*** N个边界值确定N+1 个分区

*** RIGHT - 第一个分区的所有值都小于VAL < 1997-01-1

            第二个分区的值范围是1997-01-01 <= VAL < 1998-01-01

***************************************************************/

CREATE PARTITION FUNCTION PF_Orders_OrderDateRange(DATETIME)

AS

RANGE RIGHT FOR VALUES

(

   '1997-01-01',

   '1998-01-01',

   '1999-01-01'

)

GO

EXEC dbo.sp_show_partition_range

     @partition_function = 'PF_Orders_OrderDateRange'

/***************************************************************

显示分区函数的分区情况,PARTITION FUNCTION,PARTITION,MinVal,VALUE,MaxVal 

PF_Orders_OrderDateRange    1    NULL                                   <= val <    

1997-01-01 00:00:00.000

PF_Orders_OrderDateRange    2    1997-01-01 00:00:00.000    <= val <    1998-01-01 

00:00:00.000

PF_Orders_OrderDateRange    3    1998-01-01 00:00:00.000    <= val <    1999-01-01 

00:00:00.000

PF_Orders_OrderDateRange    4    1999-01-01 00:00:00.000    <= val <    NULL

****************************************************************/

/***************************************************************

2. 创建了分区函数后,便可以创建分区方案

*** 因为在上一个分区函数中有个边界值,4个分区,并且并没有其它的

    数据库文件组,所以当分区方案应用到具体的分区函数时所有的分区

    都是指向PRIMARY 文件组

***************************************************************/

CREATE PARTITION SCHEME PS_Orders

AS

PARTITION PF_Orders_OrderDateRange

TO ([primary],[primary],[primary],[primary])

GO

/***************************************************************

3. 创建分区表时要应用分区方案,并提供具体的分区键列

ON 分区函数(分区键列)

****************************************************************/

CREATE TABLE dbo.Orders

(

   OrderID     INT         NOT NULL,

   CustomerID  VARCHAR(10) NOT NULL,

   EmployeeID  INT         NOT NULL,

   OrderDate   DATETIME    NOT NULL

)

ON PS_Orders(OrderDate)

GO

/******************************************************************

4. 在创建分区表后,需要创建聚集分区索引

*** 根据订单表Orders 查询时经常使用OrderDate 范围条件来查询的特点,

*** 我们最好在Orders.OrderDate 列上建立聚集索引(clustered index).

*** 为了便于进行分区切换(partition swtich)

    大多数情况下,建议在分区表上建立分区索引。

*******************************************************************/

CREATE CLUSTERED INDEX IXC_Orders_OrderDate ON dbo.Orders(OrderDate)

GO

/*******************************************************************

5. 为分区表创建主键

如果主键不包含分区键列,将会出现以下错误信息:

Msg 1908, Level 16, State 1, Line 2

Column 'OrderDate' is partitioning column of the index 'PK_Orders'.

Partition columns for a unique index must be a subset of the index key.

Msg 1750, Level 16, State 0, Line 2

Could not create constraint. See previous errors.

原因:

主键实际上是个唯一索引,但分区表在建立唯一索引(分区索引)的时候,

分区列必须是唯一索引的一部分.因为SQL Server 不但要保证索引在各个

分区是唯一的,还要保证在整个表中是唯一的.

********************************************************************/

ALTER TABLE dbo.Orders ADD CONSTRAINT PK_Orders

PRIMARY KEY(OrderID, CustomerID,OrderDate)

GO

/************************************************************************

查看分区表Orders 上的索引:

IXC_Orders_OrderDate|clustered located on PS_Orders|OrderDate

PK_Orders|nonclustered,unique,primary key located on PS_Orders|OrderID, CustomerID, 

OrderDate

************************************************************************/

EXEC sp_helpindex 'dbo.Orders'

/**********************************************************************

6. 从SQL Server 2000 NorthWind 导入测试数据

***********************************************************************/

INSERT INTO dbo.Orders

SELECT OrderID,

       CustomerID,

       EmployeeID,

       OrderDate

FROM Northwind.dbo.Orders

/************************************************************************

7. 查看分区表各分区数据情况(数据行数,最大最小OrderDate 值)

*************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

GO

/************************************************************************

在目前的测试数据中,并没有大于1999年的数据,所以在上面的查询结果中并没有

看到第个分区的信息: PARTITION,ROWS,MinVal,MaxVal

1    152    1996-07-04 00:00:00.000    1996-12-31 00:00:00.000

2    408    1997-01-01 00:00:00.000    1997-12-31 00:00:00.000

3    270    1998-01-01 00:00:00.000    1998-05-06 00:00:00.000

*************************************************************************/

-- 插入一条测试数据

INSERT INTO dbo.Orders VALUES(11111,'TEST',1,'2000-10-10 10:10:10:100')

-- 再次查询

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/************************************************************************

查询结果显示了个分区的信息

PARTITION,ROWS,MinVal,MaxVal

1    152    1996-07-04 00:00:00.000    1996-12-31 00:00:00.000

2    408    1997-01-01 00:00:00.000    1997-12-31 00:00:00.000

3    270    1998-01-01 00:00:00.000    1998-05-06 00:00:00.000

4    1        2000-10-10 10:10:10.100    2000-10-10 10:10:10.100

*************************************************************************/

GO

/*************************************************************************

************* 切换分区表的一个分区到普通数据表***************************

************* Partition to Table ****************************************/

/*************************************************************************

1. 首先建立普通数据表Orders_1998,该表用来存放订单日期为1998 年的所有数据

2. 分区到普通表的切换,最好满足以下的前提条件:

   a. 普通表必须建立在分区表切换分区所在的文件组上ON [PRIMARY]

   b. 普通表的表结构跟分区表的一致

   c. 普通表上的索引要跟分区表一致(聚集索引,非聚集索引)

   d. 普通表必须是空表,不能有任何数据

*************************************************************************/

IF OBJECT_ID('Orders_1998') IS NOT NULL

DROP TABLE Orders_1998

GO

CREATE TABLE dbo.Orders_1998

(

   OrderID     INT         NOT NULL,

   CustomerID  VARCHAR(10) NOT NULL,

   EmployeeID  INT         NOT NULL,

   OrderDate   DATETIME    NOT NULL

)ON [PRIMARY]

GO

-- 添加聚集索引,和分区表一致

CREATE CLUSTERED INDEX IXC_Orders1998_OrderDate ON dbo.Orders_1998(OrderDate)

GO

-- 添加主键,和分区表一致

ALTER TABLE dbo.Orders_1998 ADD CONSTRAINT PK_Orders_1998

PRIMARY KEY(OrderID,CustomerID,OrderDate)

GO

/***************************************************************************

** 开始切换分区表Orders 第三个分区的数据(1998年的数据)到普通表Orders_1998

** 关键字- SWITCH PARTITION [NUMBER] TO [History Table]

***************************************************************************/

ALTER TABLE dbo.Orders SWITCH PARTITION 3 TO dbo.Orders_1998

/***************************************************************************

查询源分区表结果

分区号为的数据已经没有了

1    152    1996-07-04 00:00:00.000    1996-12-31 00:00:00.000

2    408    1997-01-01 00:00:00.000    1997-12-31 00:00:00.000

4    1        2000-10-10 10:10:10.100    2000-10-10 10:10:10.100

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/***************************************************************************

查询存档表结果

3    270    1998-01-01 00:00:00.000    1998-05-06 00:00:00.000

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders_1998

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/************************************************************************

*************  切换普通表数据到分区表的一个分区中  *********************

*************    Table to Partition             ************************/ 

/*************************************************************************

上面我们已经把分区表Orders 第三个分区的数据切换到普通表Orders_1998 中了,

现在我们再切换回来:

**************************************************************************/

ALTER TABLE dbo.Orders_1998 SWITCH PARTITION 3 TO dbo.Orders

/*************************************************************************

错误信息:

Msg 4911, Level 16, State 2, Line 1

Cannot specify a partitioned table without partition number in ALTER TABLE

SWITCH statement. The table 'SSISDemoDB.dbo.Orders' is partitioned.

原因:

实际上应该是将dbo.Orders_1998 表中的数据SWITCH 到dbo.Orders 表的

Partition 分区中.

而不能说是将dbo.Orders_1998 的分区的数据SWITCH 到dbo.Orders 全表中

**************************************************************************/

ALTER TABLE dbo.Orders_1998 SWITCH TO dbo.Orders PARTITION 3

/*************************************************************************

错误信息:

Msg 4982, Level 16, State 1, Line 1

ALTER TABLE SWITCH statement failed. Check constraints of source table

'dbo.Orders_1998' allow values that are not allowed by range defined by

partition 3 on target table 'dbo.Orders'.

原因:

表dbo.Orders 的数据经过分区函数的分区列定义, 各个分区的数据实际上已经经过

了数据约束检查,符合分区边界范围(Range)的数据才会录入到各个分区中.

但是在历史表/存档表dbo.Orders_1998中的数据实际上是没有边界约束的,比如完全

可以手动的插入一条年的数据,这样一来在进行SWITCH时肯定是不会成功的.

所以在SWITCH时,先进行了约束性检查,尽管没有不符合规范的数据,但是有潜在的威胁.

所以在SWITCH之前,先为dbo.Orders_1998添加一个检查约束,并再次SWITCH,成功!

**************************************************************************/

ALTER TABLE dbo.Orders_1998 ADD CONSTRAINT CK_Orders1998_OrderDate

CHECK(OrderDate>='1998-01-01' AND OrderDate<'1999-01-01')

ALTER TABLE dbo.Orders_1998 SWITCH TO dbo.Orders PARTITION 3 

/***************************************************************************

查询源分区表结果,分区的数据已经从dbo.Orders_1998 回来了

1    152    1996-07-04 00:00:00.000    1996-12-31 00:00:00.000

2    408    1997-01-01 00:00:00.000    1997-12-31 00:00:00.000

3    270    1998-01-01 00:00:00.000    1998-05-06 00:00:00.000

4    1        2000-10-10 10:10:10.100    2000-10-10 10:10:10.100

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/***************************************************************************

查询存档表结果,没有任何数据,已经成功SWITCH to Orders 表的PARTITION 3

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders_1998

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/****************************************************************************

所以在进行存档表的数据向分区表迁移过程中(TABLE TO PARTITION),

相比(PARTITION TO TABLE)多一个条件:

普通表必须加上和分区数据范围一致的约束条件.

*****************************************************************************/

/************************************************************************

*************  切换分区表数据到分区表   ********************************

*************    PARTITION TO PARTITION  **********************************/

/*************************************************************************

-- 新的存档分区表在结构上和源分区表是一致的,包括分区函数和分区方案,

但是需要重新创建,不能简单地直接使用dbo.Orders 表上的分区函数和分区方案,

因为他们之间有绑定关系. 

**************************************************************************/

IF OBJECT_ID('OrdersArchive') IS NOT NULL

DROP TABLE OrdersArchive

GO

IF EXISTS (SELECT * FROM sys.partition_schemes WHERE name = 'PS_OrdersArchive')

DROP PARTITION SCHEME PS_OrdersArchive

GO

IF EXISTS (SELECT * FROM sys.partition_functions WHERE name = 

'PF_OrdersArchive_OrderDateRange')

DROP PARTITION FUNCTION PF_OrdersArchive_OrderDateRange

GO

CREATE PARTITION FUNCTION PF_OrdersArchive_OrderDateRange(DATETIME)

AS

RANGE RIGHT FOR VALUES

(

   '1997-01-01',

   '1998-01-01',

   '1999-01-01'

)

GO

CREATE PARTITION SCHEME PS_OrdersArchive

AS

-- 分区Scheme和分区函数绑定了

PARTITION PF_OrdersArchive_OrderDateRange

TO ([primary],[primary],[primary],[primary])

GO

CREATE TABLE dbo.OrdersArchive

(

   OrderID     INT         NOT NULL,

   CustomerID  VARCHAR(10) NOT NULL,

   EmployeeID  INT         NOT NULL,

   OrderDate   DATETIME    NOT NULL

)

-- 表和分区Scheme绑定了

ON PS_OrdersArchive(OrderDate)

GO

CREATE CLUSTERED INDEX IXC_OrdersArchive_OrderDate ON dbo.OrdersArchive(OrderDate)

ALTER TABLE dbo.OrdersArchive ADD CONSTRAINT PK_OrdersArchive

PRIMARY KEY(OrderID, CustomerID,OrderDate)

GO

/*********************************************************************************

开始切换分区

**********************************************************************************/

ALTER TABLE dbo.Orders SWITCH PARTITION 1  TO dbo.OrdersArchive PARTITION 1

ALTER TABLE dbo.Orders SWITCH PARTITION 2  TO dbo.OrdersArchive PARTITION 2

ALTER TABLE dbo.Orders SWITCH PARTITION 3  TO dbo.OrdersArchive PARTITION 3

/***************************************************************************

查询源分区表结果,只会有分区的数据

4    1    2000-10-10 10:10:10.100    2000-10-10 10:10:10.100

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_Orders_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.Orders

GROUP BY $PARTITION.PF_Orders_OrderDateRange(OrderDate)

ORDER BY PARTITION

/***************************************************************************

查询存档表结果,已经成功转移

1    152    1996-07-04 00:00:00.000    1996-12-31 00:00:00.000

2    408    1997-01-01 00:00:00.000    1997-12-31 00:00:00.000

3    270    1998-01-01 00:00:00.000    1998-05-06 00:00:00.000

***************************************************************************/

SELECT PARTITION = $PARTITION.PF_OrdersArchive_OrderDateRange(OrderDate),

       ROWS      = COUNT(*),

       MinVal    = MIN(OrderDate),

       MaxVal    = MAX(OrderDate)

FROM dbo.OrdersArchive

GROUP BY $PARTITION.PF_OrdersArchive_OrderDateRange(OrderDate)

ORDER BY PARTITION

/***************************************************************************

总结: 分区表分区切换并没有真正去移动数据,而是SQL Server 在系统底层改变了表

的元数据。因此分区表分区切换是高效,快速,灵活的.利用分区表的分区切换功能,

我们可以快速加载数据到分区表.卸载分区数据到普通表,然后TRUNCATE 普通表,

以实现快速删除分区表数据,快速归档不活跃数据到历史表。

****************************************************************************/

注 : 已经不记得原博客地址了, 这篇日志是基于别人的分析成果之上加上自己亲自实践, 思考, 重 新添加了一些代码和注释. 在注解和结论验证方面按照自己的理解做出了还算比较细致的说明,对刚接触 表分区概念的朋友们相信会有很大的帮助. 我也是通过这种方式学习和掌握了表分区的一些基础操作步 骤和处理方式.

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索scheme
, 函数
, 分区表
, partition
边界
biwork、实践笔记、冬季旅游的实践笔记、小学生实践笔记、实践笔记400字,以便于您获取更多的相关知识。

时间: 2024-09-18 18:23:37

BIWORK 分区表阅读与实践笔记的相关文章

《深入理解Nginx》阅读与实践(三)

使用upstream和subrequest访问第三方服务 一.upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例(一)模块框架 首先要明确的是,这里是编写一个使用upstream的模块,而不是编写upstream模块.因此,和HelloWorld类似,模块结构体ngx_http_mytest_module.模块上下文结构体ngx_http_mytest_module_ctx.数组ngx_http_mytest_command[].方法ngx_http_mytes

《深入理解Nginx》阅读与实践(二) 配置项的使用

HelloWorld的完成意味着已经踏入了nginx的大门,虽然很振奋人心,但在编写中仍有很多疑惑的存在:nginx.conf的配置项中各个参数是如何读入程序中的?ngx_command_t如何完成配置项的读入工作?名称相同的配置项的冲突如何解决?HelloWorld中的ngx_http_module_t何以称为模块的上下文?同时我在读第4章"配置项的使用"时又有成见:不就是各种琐碎的参数设置嘛,有什么好读的?(这个成见来自于UNP中某一章节套接字选项)不过经过仔细阅读并实践这部分内容

#实践笔记#Ubuntu配置Apache+PHP+MySQL_Linux

在我早先的一篇文章<#实践笔记#本地配置PHPnow与WordPress>,已经讨论过PHPnow的本地安装教程.但是PHPnow套件是Windows平台下的软件,不适用我现在使用的平台.所以笔者此次尝试了在Ubuntu 11.10平台下的本地服务器配置(配置Apache+PHP+MySQL). 废话少说,步入整体.   流程笔记: 1.打开终端,输入"sudo apt-get install apache2",回车;(安装apache2.0)   2.如有密码请再输入管理

UE实践笔记:敏捷人种志研究

近期有机会展开实地调研,尝试将ethnography(人种志)方法用起来,但我远不敢称此类研究就是人种志研究了,最多能算是以下这张IDEO方法卡所谓的敏捷人种志研究--   HOW:花时间与你的用户.在他们熟悉的环境中接触,从而观察并参与他们的一些日常活动. WHY:这个方法能让你切身体会你的用户的习惯.习俗,他们所使用的语言,以及一些活动或物件对他们来说有怎样的意义. 这几次针对卖家的实地调研给我的启发不是一般大,有几个夜晚甚至兴奋得辗转难眠. 1. 大量的问题,大量的研究.设计机会与挑战 之

《深入理解Nginx》阅读与实践(一) Nginx安装配置与HelloWorld

最近在读陶辉的<深入理解Nginx:模块开发与架构解析>,一是想跟着大牛练练阅读和编写开源代码的能力,二是想学学Nginx优秀的架构设计,三是想找一个点深入下Linux下网络编程的细节.侯捷在他的<STL源码剖析>的自序里说过,"追踪一流作品并于其中吸取养分,远比自己关起门来写个三流作品,价值高得多".我个人比较喜欢<深入理解Nginx>这本书,它讲解的很全面,相关的知识都会有所介绍,整体的脉络比较明晰.只是涉及东西比较多,有时真希望纸质文档也能像在

UE实践笔记:KJ法在用户研究中的应用

去年偶尔看到一篇将KJ法在UX界应用的文章,于是在后续两个项目中尝试使用了一下.下面结合两个实例,介绍这种好记又好用的方法. 一.KJ法简介 KJ法又名亲和图法,是日本人类学家川喜田二郎所发明.人类学家在田野调查中(所谓实地调研或人种志调研)会收集到大量相对零散的事实,如何对这些定性的素材进行有效的比较和分类.识别规律,从而建立假说或发展理论呢?KJ法最原始的核心就在于解决这一问题.也正因此,它十分适合用于UDC流程中的需求探索阶段. 后期,川喜田二郎将KJ法与头脑风暴法结合,使该方法广泛应用在

阅读&lt;php程序设计&gt;笔记

今天知道了哪些注释风格是从哪些语言演变过来的了. /**/是c语言的注释风格. //是c++的语言注释风格 原来php还有种类似shell的注释风格:# 原来php是作为一shell程序进行解析的.这种情况发生在:编译php的时候,没有指定任何服务器类型.那么就表示不作为服务器的一个模块了.这个时候就是以命令行的方式调用了. 难怪:大公司为什么要求要熟悉shell编程.难道,他们是将php作为一个命令行程序执行吗? 现在发现连php圣经中的作者估计也没有完全理解 $a = $b;.在其书中,提到

UX实践笔记:Mapping法的一些应用

Mapping概念论 Mapping的概念见于逻辑学.语言学.心理学领域.最简单的理解是,Mapping指通过一个概念领域来理解另一个概念领域,比如说"恋爱是一场旅行".恋爱与旅行之间建立了映射关系. 在设计研究中邀请用户完成Mapping的过程,可以理解为,通过可视化的手段,在抽象与具象之间建立映射关系,构筑问题空间(problem-space)或设计空间(http://www.aliyun.com/zixun/aggregation/29798.html">desi

Yeoman学习与实践笔记

Yeoman是Google的团队和外部贡献者团队合作开发的,他的目标是通过Grunt(一个用于开发任务自动化的命令行工具)和Bower(一个HTML.CSS.Javascript和图片等前端资源的包管理器)的包装为开发者创建一个易用的工作流. Yeoman的目的不仅是要为新项目建立工作流,同时还是为了解决前端开发所面临的诸多严重问题,例如零散的依赖关系. Yeoman主要有三部分组成:yo(脚手架工具).grunt(构建工具).bower(包管理器).这三个工具是分别独立开发的,但是需要配合使用