SQL Server 表分区之水平表分区

转自:https://www.cnblogs.com/Brambling/p/6766482.html

什么是表分区?

表分区分为水平表分区和垂直表分区,水平表分区就是将一个具有大量数据的表,进行拆分为具有相同表结构的若干个表;而垂直表分区就是把一个拥有多个字段的表,根据需要进行拆分列,然后根据某一个字段进行关联。

表分区分为以下五个步骤:

1、创建文件组

2、创建数据文件

3、创建分区函数

4、创建分区方案

5、创建分区表

水平表分区

创建文件组:

语法:

-- 创建文件组语法
alter database <数据库名> add filegroup <文件组名>

alter database Test add filegroup GroupOnealter database Test add filegroup GroupTwoalter database Test add filegroup GroupThreealter database Test add filegroup GroupFouralter database Test add filegroup GroupFive

创建数据文件到指定文件组:

语法:

-- 创建数据文件到指定文件组语法alter database <数据库名称> add file <文件属性> to filegroup <文件组名称><文件属性>
(name=文件的逻辑名称,filename=文件的物理名称,size=文件初始大小,filegrowth=文件自动增长量(数值或百分比),maxsize=文件增长的最大值
)

alter database Test add file
(name=N'OneFile',filename=N'D:\DataDB\OneFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupOnealter database Test add file
(name=N'TwoFile',filename=N'D:\DataDB\TwoFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupTwoalter database Test add file
(name=N'ThreeFile',filename=N'D:\DataDB\ThreeFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupThreealter database Test add file
(name=N'FourFile',filename=N'D:\DataDB\FourFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupFouralter database Test add file
(name=N'FiveFile',filename=N'D:\DataDB\FiveFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupFive

创建分区函数:

创建一个分区函数,创建分区函数的目的是告诉 SQL Server 以什么方式对分区表进行分区。

语法:

create partition function    -- 创建分区函数
Part_Fun(int)    -- 分区函数名(分区列类型)
as range [left/right]    -- 左置/右置,即边界值的存储位置,如果设置为右置,边界值存到下一个表
for values ('1000','2000','3000','4000','5000')        -- 设置每个分区表的边界值 

create partition function
Part_Fun(int)
as range right
for values ('1000','2000','3000','4000','5000')        

删除分区函数:

--删除分区函数语法
drop partition function <分区函数名>--删除名为 Part_Fun 的分区函数
drop partition function Part_Fun

PS:只有当分区函数没有应用到分区方案中时,指定的分区函数才能被删除。

创建分区方案:

分区方案的作用是将分区函数生成的分区映射到文件组中去。分区函数的作用是告诉SQL Server,如何将数据进行分区,而分区方案的作用则是告诉 SQL Server 将已分区的数据放在哪个文件组中。

语法:

--创建分区方案语法
create partition scheme        -- 创建分区方案
<分区方案名称>    -- 分区方案名称
as partition <分区函数名称>    -- 指定分区函数名称
to (文件组名称,,,,)    -- 指定分区函数划分出来的数据对应存放的文件组

create partition scheme        -- 创建分区方案
Part_Plan    -- 分区方案名称
as partition Part_Fun    -- 分区函数名称
to ('GroupOne','GroupTwo','GroupThree','GroupFour','GroupFive') -- 分区文件组

一执行,结果报错了。

不对呀,我明明建立的是五个分区文件组,分区函数也是分为五份的啊。其实这里的意思应该就是后续数据的问题了,首先不可能保证这个表永远就 5000 条数据的,所以他在这里的意思就是后续数据存储的文件组。这里我把后续数据放在最后一个文件组里面。

create partition scheme        -- 创建分区方案
Part_Plan    -- 分区方案名称
as partition Part_Fun    -- 分区函数名称
to ('GroupOne','GroupTwo','GroupThree','GroupFour','GroupFive','GroupFive') -- 分区文件组

删除分区方案:

--删除分区方案语法
drop partition scheme<分区方案名称>--删除名为 Part_Plan 的分区方案
drop partition scheme Part_Plan

PS:当没有分区表引用该分区方案时,才能对其进行删除。

创建分区表:

语法:

--创建分区表语法
create table <表名>    -- 表名称
(column1        int        not null  primary key nonclustered,    -- 字段名称、字段类型、是否可空、主键约束、非聚集索引column2        int        not null
) on <分区方案名>(分区列名)        -- 分区方案的名称(指定要依据分区的列名)

create table US_Info
(ID        int        not null    primary key identity(1,1),Name    nvarchar(32)    null,CreateTime    nvarchar(32)    null
)on Part_Plan(ID)

PS:如果在表中创建有主键、唯一索引、聚集索引,则分区依据列必须为该列之一。即分区依据列必须建立在主键、唯一索引、聚集索引之上。

创建分区索引:

语法:

--创建分区索引语法
create [ unique [ clustered | nonclustered ] ]  -- unique 唯一    clustered 聚集    nonclustered 非聚集
index <索引名称>    -- 指定索引名称
on <表名>(列名)        -- 指定表名(指定列名)
on <分区方案名>(分区依据列名)    -- 分区方案名称(分区依据列名)

create nonclustered
index Part_Non_Name
on US_Info(Name)
on Part_Plan(ID)    

在表 US_Info 中插入5000条数据:

declare @I    int
set @I=1
while(@I<=5000)
begininsert into US_Info(Name,CreateTime)values('名称'+convert(nvarchar,@I),Convert(nvarchar,GETDATE(),121))set @I=@I+1
endselect * from US_Info

查询指定值位于数据表哪个分区中:

-- 查询指定值位于数据表哪个分区中select $partition.Part_Fun('3050')    -- 返回 4,表示位于第四个分区中

查询分区表中,每个分区存在的数据的行数:

--查看分区表中,每个分区存在的数据的行数select $partition.Part_Fun(ID) as Part_Num,count(1) as R_Count
from US_Info
group by  $partition.Part_Fun(ID)

查询指定分区中的数据:

-- 查询指定分区中的数据select * from US_Info
where $partition.Part_Fun(ID)=3

拆分分区:

在分区函数中新增一个边界值,即可将 1 个分区拆分为 2 个。

--将第 3 个分区拆分为 2 个分区
alter partition function Part_Fun()
split range(N'2500')  

一执行,报错了,拆分不了,因为前面我们已经用分区函数指定了分区和文件组,那就要先添加一个文件组。

为分区方案指定下一个文件组:

-- 添加一个文件组 GroupSix
alter database Test add filegroup GroupSix-- 添加一个数据文件
alter database Test add file
(name=N'SixFile',filename=N'D:\DataDB\SixFile.mdf',size=3MB,filegrowth=10%,maxsize=unlimited    -- 无限大小
)
to filegroup GroupSix-- 为分区方案指定下一个文件组alter partition scheme Part_Plan  -- 分区方案名称
next used GroupSix    -- 下一个文件组名称

然后再来对分区进行拆分:

--将第 3 个分区拆分为 2 个分区
alter partition function Part_Fun()    -- 分区函数
split range        -- 分割界限
(N'2500')  -- 分区界限值

合并分区:

与拆分分区相反,去除一个边界值即可。

-- 将第 3 个分区与第 4 个分区合并
alter partition function Part_Fun()     -- 分区函数
merge range        -- 合并界限
(N'2500')  -- 合并界限值

复制分区表中的数据到普通表:

复制分区表中的数据到普通表需要满足以下条件:

数据表的结构必须相同,即字段数量、字段类型等,字段与字段之间必须对应。

两个表必须位于同一文件组,所以创建普通表的时候就需要指定文件组。

create table US_Info_back        -- 创建普通表的表名
(ID        int        not null    primary key identity(1,1),    -- 列定义Name    nvarchar(32)    null,CreateTime    nvarchar(32)    null
)on GroupThree    -- 指定文件组

将分区表中的数据复制到普通表:

-- 将分区表 US_Info 中的第 3 个分区的数据复制到普通表 US_Info_back 中alter table US_Info
switch partition 3
to US_Info_backselect * from US_Info_back

将普通表中的数据复制到分区表:

--将普通表 US_Info_back 中的数据复制到分区表 US_Info 中的第 6 个分区alter table US_Info_back    -- 普通表名
switch to US_Info    -- 分区表名
partition 6        -- 指定分区

PS:将普通表中的数据复制到分区表时,需要先删除分区表的索引。

将普通表转换为分区表:

当数据库已经存在数据的时候,就不能像上面那样直接建立分区表了,只能将普通表转换为分区表,只需在该普通表上创建一个聚集索引,并在该聚集索引中使用分区方案即可。

如果是已经存在的聚集索引,那么需要删除然后重新建立,并使用分区方案。

现在我有一个现成的表 UserInfo,因为它存在一个主键,而建立主键时,系统会自动为主键列添加聚集索引,因为这个聚集索引没法删除,所以我现在要先删除这个主键,然后重新建立一个主键,并设置为非聚集索引,然后为主键创建一个聚集索引(会覆盖非聚集索引),并使用分区方案指定分区列即可。

-- 根据 指定表名 查询 表的约束
exec sp_helpconstraint UserInfo      -- UserInfo 表名-- 根据指定主键约束名删除指定表的主键约束
alter table UserInfo drop constraint PK__UserInfo__5A2040BBA6D6767A -- 添加主键约束,但设置为非聚集索引
alter table UserInfo add constraint PK__UserInfo__5A2040BBA6D6767A primary key nonclustered (U_Id)-- 添加一个聚集索引,并使用分区方案指定分区的列create clustered index CLU_StuNo -- 索引名称
on UserInfo(U_Id)  -- 指定添加索引的表(添加索引的列)
on Part_Plan(U_Id)        -- 分区方案名称(分区依据的列)

为这个表也插入5000条数据,看看效果:

declare @I    int
select @I=U_Id from UserInfo order by U_Id desc
while(@I<=5000)
begininsert into UserInfo(U_No,U_Name,U_Pwd)values('demo'+convert(nvarchar,@I),'demo'+convert(nvarchar,@I),'40D1C69C7B86064EA140C13CE8ED0E15')set @I=@I+1
endselect * from UserInfo
go

查看分区表中,每个分区存在的数据的行数:

--查看分区表中,每个分区存在的数据的行数
select $partition.Part_Fun(U_Id) as Part_Num,count(1) as R_Count
from UserInfo
group by  $partition.Part_Fun(U_Id)
order by Part_Num 

查看数据库分区信息 SQL(复制来的):

SELECT OBJECT_NAME(p.object_id) AS ObjectName,i.name                   AS IndexName,p.index_id               AS IndexID,ds.name                  AS PartitionScheme,   p.partition_number       AS PartitionNumber,fg.name                  AS FileGroupName,prv_left.value           AS LowerBoundaryValue,prv_right.value          AS UpperBoundaryValue,CASE pf.boundary_value_on_rightWHEN 1 THEN 'RIGHT'ELSE 'LEFT' END    AS Range,p.rows AS Rows
FROM sys.partitions                  AS p
JOIN sys.indexes                     AS iON i.object_id = p.object_id AND i.index_id = p.index_id
JOIN sys.data_spaces                 AS dsON ds.data_space_id = i.data_space_id
JOIN sys.partition_schemes           AS psON ps.data_space_id = ds.data_space_id
JOIN sys.partition_functions         AS pfON pf.function_id = ps.function_id
JOIN sys.destination_data_spaces     AS dds2ON dds2.partition_scheme_id = ps.data_space_id AND dds2.destination_id = p.partition_number
JOIN sys.filegroups                  AS fgON fg.data_space_id = dds2.data_space_id
LEFT JOIN sys.partition_range_values AS prv_leftON ps.function_id = prv_left.function_id AND prv_left.boundary_id = p.partition_number - 1
LEFT JOIN sys.partition_range_values AS prv_rightON ps.function_id = prv_right.function_id AND prv_right.boundary_id = p.partition_number
WHERE OBJECTPROPERTY(p.object_id, 'ISMSShipped') = 0
UNION ALL
SELECTOBJECT_NAME(p.object_id)    AS ObjectName,i.name                      AS IndexName,p.index_id                  AS IndexID,NULL                        AS PartitionScheme,p.partition_number          AS PartitionNumber,fg.name                     AS FileGroupName,  NULL                        AS LowerBoundaryValue,NULL                        AS UpperBoundaryValue,NULL                        AS Boundary, p.rows                      AS Rows
FROM sys.partitions AS p
JOIN sys.indexes AS i ON i.object_id = p.object_id AND i.index_id = p.index_id
JOIN sys.data_spaces AS ds ON ds.data_space_id = i.data_space_id
JOIN sys.filegroups AS fg ON fg.data_space_id = i.data_space_id
WHERE OBJECTPROPERTY(p.object_id, 'ISMSShipped') = 0
ORDER BY ObjectName,IndexID,PartitionNumber

参考:

http://www.cnblogs.com/knowledgesea/p/3696912.html

http://blog.csdn.net/lgb934/article/details/8662956

转载于:https://www.cnblogs.com/gered/p/8074747.html

SQL Server2008及以上 表分区操作详解相关推荐

  1. MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测) 一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过 ...

  2. mysql 社区版 innodb_MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测) / --------------------         写在最前面            ------------------ ...

  3. SQL Server 默认跟踪 -- 捕获事件详解

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

  4. Mysql 多表查询详解

    Mysql 多表查询详解 一.前言  二.示例 三.注意事项 一.前言  上篇讲到Mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...

  5. 【深度好文】Flink SQL流批⼀体化技术详解(一)

    持续输出 敬请关注 大数据架构  湖仓一体化  流批一体 离线+实时数仓  各种大数据解决方案  各种大数据新技术实践 持续输出  敬请关注 [珍藏版]数仓平台.推荐系统架构选型及解决⽅案_大数据研习 ...

  6. Oracle表空间_PK是什么意思,Oracle表空间详解

    关键字:Oracle表空间详解 一.============  查询 =================== 1.查询oracle用户的默认表空间和临时表空间 select default_table ...

  7. 大数据单机学习环境搭建(5)Hive建表DDL详解

    专题:大数据单机学习环境搭建和使用 1. Hive建表简单示例 1.1.Hive建表语句 1.2.表详细信息 1.3.数据展示 2. Hive建表语法详解 3.拓展1:复杂数据分割 4.拓展2:事务表 ...

  8. js入门·表单详解一(修改表单属性,修改表单元素值)

    实在javascript入门·Document对象入门讲解(访问表单,创建新页,获取页标题) 一文中,我们已经把表单的一些基本访问等弄清楚了,下面我们深入的学下表单的属性以及对表单元素的简单操作! 演 ...

  9. (转)CentOS分区操作详解

    CentOS分区操作详解 原文:http://blog.csdn.net/yonggeit/article/details/77924393 磁盘分区 分区格式的两种选择:MBR和GPT 分区命令: ...

最新文章

  1. element 如何自定义svg图标_4000+免费可自定义的图标集合
  2. Vue之vue-cli安装与简单调试
  3. 序列号生成的另一种玩法
  4. python变量如何使用,python如何使用变量
  5. Kotlin实践(3)-入口 函数
  6. XP Sp2下双机通过无线网卡实现Internet共享
  7. 免费生成https证书以及配置
  8. 常用的python测试脚本_详解Python的单元测试
  9. 机器学习(十四)Libsvm学习笔记
  10. Android开发 无线Wifi+WifiUtil工具类,直面秋招
  11. 闲鱼日出2000单,不对称信息差的好项目
  12. 非致命战计算机病毒战属于,《信息化战争》章节
  13. python打造批量关键词排名查询工具
  14. 无法打开excel powermap 三维地图
  15. CS61B project 2 示例图的地牢地图房间走廊地图生成洞穴地图生成方法
  16. 数字签名与数字证书技术简介(二)
  17. Java最新面试题100道,包含答案示例(41-50题)
  18. 伴随着我娃成长的运维平台(图片持续更新..)
  19. 机器学习-贝叶斯分类
  20. 码住这些视频配音软件,一键完成配音

热门文章

  1. VB6基本数据库应用(五):数据的查找与筛选
  2. PHP使用APNS的 feedback service
  3. 草根创业都选择的是什么人?
  4. J2EE复习(二)XML
  5. 开源项目贡献者_嘿新手开源贡献者:请写博客。
  6. 白盒测试之基本路径覆盖测试
  7. Python培训班线上线下哪种靠谱
  8. 接口测试要如何做数据准备
  9. spring ioc原理分析
  10. Java基础学习总结(13)——流IO