Partition:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表的老数据,十分高效,switch操作不会移动数据,只是做元数据的置换,因此,执行分区切换操作的时间是非常短暂的,几乎是瞬间完成,但是,在做分区切换时,源表和靶表必须满足一定的条件:
- 表的结构相同:列的数据类型,可空性(nullability)相同;
- 索引结构必须相同:索引键的结构,聚集性,唯一性,列的可空性必须相同;
- 主键约束:如果源表存在主键约束,那么靶表必须创建等价的主键约束;
- 唯一约束:唯一约束可以使用唯一索引来实现;
- 索引键的结构:索引键的顺序,包含列,唯一性,聚集性都必须相同;
- 存储的数据空间(data space)相同:源表和靶表必须创建在相同的FileGroup或Partition Scheme上;
分区切换是将源表中的一个分区,切换到靶表(target_table)中,靶表可以是分区表,也可以不是分区表,switch操作的语法是:
ALTER TABLE schema_name . table_name
SWITCH [ PARTITION source_partition_number_expression ]
TO target_table [ PARTITION target_partition_number_expression ]
一,创建示例数据
-- create parition function
create partition function pf_int_left (int)
as range left
for values (10,20); --create partition scheme
create partition scheme ps_int_left
as
partition pf_int_left
all to ([primary]); --create partitioned table
create table dbo.dt_partition
(
ID int null,
Code int null
)
on ps_int_left (id) --Create staging table
create table dbo.dt_SwitchStaging
(
ID int null,
Code int null
)
on [primary]
创建靶表 dt_SwitchStaging,用于存储分区表的数据
二,源表和目标表的结构必须相同
1,数据列的可空性必须相同(nullability)
由于靶表的ID列是非空的(not null),源表的ID列是可空的(null),可空性不同,在切换分区时,SQL Server会抛出错误消息:
alter table dbo.dt_SwitchStaging
alter column ID int not null; --swith partition 2 to staging table
alter table dbo.dt_partition
switch partition 2
to dbo.dt_SwitchStaging
ALTER TABLE SWITCH statement failed because column 'ID' does not have the same nullability attribute in tables 'dbo.dt_partition' and 'dbo.dt_SwitchStaging'.
2,数据列的数据类型必须相同
在执行分区切换时,源表和靶表的数据类型必须相同,即使数据类型相兼容,SQL Server会抛出错误消息:
alter table dbo.dt_SwitchStaging
alter column ID bigint null
ALTER TABLE SWITCH statement failed because column 'ID' has data type int in source table 'dbo.dt_partition' which is different from its type bigint in target table 'dbo.dt_SwitchStaging'.
三,隐式的Check约束,实现分区的可空属性
分区列(Partition Column)允许为NULL,SQL Server在分区时,将NULL值作为最小值,存储在最左边的第一个分区中,其Partition Number是1。
Any data with a NULL in the partition column will reside in the leftmost partition. NULL is considered smaller than the minimum value of the data type’s values.
分区函数(Partition Function)定义分区列(Partition Column)在每一个分区的取值区间(Value Range),在SQL Server内部,取值区间是使用Check约束来实现的,每一个Partition都有一个check 约束,用于限定Partition column的取值范围:
- Partition Number=1,Partition column允许存在null;
- 其他Partition,Partition column不允许存在null;
对于Unknown值,Check约束认为逻辑结果是True,例如,check(ID>1 and ID<10), 如果ID=Null,那么表达式ID>1 and ID<10 返回Unknown(或null),但是,Check约束返回的结果是True,即不违反check约束。
四,表的索引结构必须相同,唯一性和聚集性也必须相同
在执行分区切换时,表的索引结构,唯一性和聚集性必须相同,在SQL Server中,使用unique index 实现unique 约束的唯一性。
1,索引的聚集性
在分区表上创建一个聚集索引(clustered index),在切换分区时,SQL Server抛出错误信息,要求靶表必须创建聚集索引
--create clustered index
create clustered index cix_dt_partition_ID
on dbo.dt_partition(ID)
ALTER TABLE SWITCH statement failed. The table 'dbo.dt_partition' has clustered index 'cix_dt_partition_ID' while the table 'dbo.dt_SwitchStaging' does not have clustered index.
2,唯一约束
在分区表上创建唯一聚集约束(unique clustered),在切换分区时,SQL Server抛出错误消息,要求靶表必须创建唯一索引
alter table dbo.dt_partition
add constraint UQ__dt_partition_ID_Code
unique clustered(ID,Code)
ALTER TABLE SWITCH statement failed. The table 'dbo.dt_partition' has clustered index 'UQ__dt_partition_ID_Code' while the table 'dbo.dt_SwitchStaging' does not have clustered index.
Workaround1:在靶表上创建唯一聚集索引(unique clustered),而不是创建unique clustered 约束,switch 成功;
--create unique clustered index
create unique clustered index ucix_dt_SwitchStaging_ID_Code
on dbo.dt_SwitchStaging(ID,Code)
Workaround2:在靶表上创建unique clustered 约束,switch 成功;
3,主键约束
在创建Primary key 约束时,主键列是不可空的
--drop table
drop table dbo.dt_partition
go
drop table dbo.dt_SwitchStaging
GO
--create partitioned table
create table dbo.dt_partition
(
ID int not null,
Code int null,
)
on PS_int_Left (ID)
go
--Create staging table
create table dbo.dt_SwitchStaging
(
ID int not null,
Code int null
)
on [primary]
go
为分区表创建主键约束,使用唯一聚集索引(unique clustered)实现,跟唯一聚集约束的唯一区别是唯一约束列允许为NULL
alter table dbo.dt_partition
add constraint PK__dt_partition_ID
primary key clustered(ID)
将分区表的第二个分区切换到靶表,SQL Server抛出错误信息,要求靶表必须创建唯一聚集索引,注意,不是创建聚集主键;
--swith partition 2 to staging table
alter table dbo.dt_partition
switch partition 2
to dbo.dt_SwitchStaging
ALTER TABLE SWITCH statement failed. The table 'dbo.dt_partition' has clustered index 'PK__dt_partition_ID' while the table 'dbo.dt_SwitchStaging' does not have clustered index.
在靶表上创建唯一聚集索引,在执行分区切换时,SQL Server抛出错误消息:没有等价的索引,这是因为聚集主键创建的索引是唯一的,聚集的,非空的,而唯一聚集索引是唯一的,聚集的,可空的,两者不是完全等价的。
--create unique clustered index
create unique clustered index cix_dt_SwitchStaging_ID
on dbo.dt_SwitchStaging(ID)
ALTER TABLE SWITCH statement failed. There is no identical index in source table 'dbo.dt_partition' for the index 'cix_dt_SwitchStaging_ID' in target table 'dbo.dt_SwitchStaging' .
在靶表上创建聚集主键,switch成功
--add primary key clustered constraint
alter table dbo.dt_SwitchStaging
add constraint PK__dt_SwitchStaging_ID
primary key clustered(ID)
五,总结
在执行分区操作时,要求源表和靶表必须满足:
- 表的结构相同:列的数据类型,可空性(nullability)相同;
- 索引结构必须相同:索引键的结构,聚集性,唯一性,列的可空性必须相同;
- 主键约束:如果源表存在主键约束,那么靶表必须创建等价的主键约束;
- 唯一约束:唯一约束可以使用唯一索引来实现;
- 索引键的结构:索引键的顺序,包含列,唯一性,聚集性都必须相同;
- 存储的数据空间(data space)相同:源表和靶表必须创建在相同的FileGroup或Partition Scheme上;
参考文档:
Partition:分区切换(Switch)的更多相关文章
- Partition3:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...
- SQL Server 2005 分区表实践——分区切换
本文演示了 SQL Server 2005 分区表分区切换的三种形式: 1. 切换分区表的一个分区到普通数据表中:Partition to Table: 2. 切换普通表数据到分区表的一个分区中:Ta ...
- Hadoop(17)-MapReduce框架原理-MapReduce流程,Shuffle机制,Partition分区
MapReduce工作流程 1.准备待处理文件 2.job提交前生成一个处理规划 3.将切片信息job.split,配置信息job.xml和我们自己写的jar包交给yarn 4.yarn根据切片规划计 ...
- mysql Partition(分区)初探
mysql Partition(分区)初探 表数据量大的时候一般都考虑水平拆分,即所谓的sharding.不过mysql本身具有分区功能,可以实现一定程度 的水平切分. mysql是具有MERG ...
- MySQL partition分区I
http://blog.csdn.net/binger819623/article/details/5280267 一. 分区的概念二. 为什么使用分区?(优点)三. ...
- MYSQL之水平分区----MySQL partition分区I(5.1)
一. 分区的概念 二. 为什么使用分区?(优点) 三. 分区类型 四. 子分区 五. 对分区进行修改(增加.删除.分解.合并) 六 ...
- kafka之partition分区及副本replica升级
修改kafka的partition分区 bin/kafka-topics.sh --zookeeper datacollect-2:2181 --alter --partitions 3 --topi ...
- mysql的partition分区
前言:当一个表里面存储的数据特别多的时候,比如单个.myd数据都已经达到10G了的话,必然导致读取的效率很低,这个时候我们可以采用把数据分到几张表里面来解决问题.方式一:通过业务逻辑根据数据的大小通过 ...
- Hadoop值Partition分区
分区操作 为什么要分区? 要求将统计结果按照条件输出到不同文件中(分区).比如:将统计结果按 照手机归属地不同省份输出到不同文件中(分区) 默认 partition 分区 /** 源码中:numRed ...
随机推荐
- Unity3d学习 相机的跟随
最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码: using Unit ...
- ASP.NET Core 1.1.0 Release Notes
ASP.NET Core 1.1.0 Release Notes We are pleased to announce the release of ASP.NET Core 1.1.0! Antif ...
- 通往全栈工程师的捷径 —— react
腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...
- 07. Web大前端时代之:HTML5+CSS3入门系列~H5 地理位置
Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 源码:https://github.com/duniti ...
- 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二)
前言 文章 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 中,已经完成对 gulp 的安装,由于是window环境,文中特意提到了可以通过安装 gitbash 来代替 ...
- 算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...
- C#中如何创建PDF网格并插入图片
这篇文章我将向大家演示如何以编程的方式在PDF文档中创建一个网格,并将图片插入特定的网格中. 网上有一些类似的解决方法,在这里我选择了一个免费版的PDF组件.安装控件后,创建新项目,添加安装目录下的d ...
- [转载]Cookie/Session的机制与安全
Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...
- ORACLE中STATUS为INACTIVE但是SERVER为SHARED状态的会话浅析
我们知道当ORACLE数据库启用共享服务器模式时,通过共享服务器模式连接到数据库的会话是有一些特征的.在v$session里面,其SERVER的状态一般为SHARED和NONE, 为SHARED时,表 ...
- 【每日一linux命令1】linux命令路径
一.路径: 执行命令前必须要考虑的一步是命令的路径,若是路径错误或是没有正确的指定,可能导致错误 的执行或是找不到该命令.要知道设置的路径,可执行以下命令: echo $PATH 显示结果: 这时我们 ...