什么是表分区?

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

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

1、创建文件组

2、创建数据文件

3、创建分区函数

4、创建分区方案

5、创建分区表

水平表分区

创建文件组:

语法:

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

alter database Test add filegroup GroupTwo

alter database Test add filegroup GroupThree

alter database Test add filegroup GroupFour

alter 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 GroupOne

alter database Test add file
(
    name=N'TwoFile',
    filename=N'D:\DataDB\TwoFile.mdf',
    size=3MB,
    filegrowth=10%,
    maxsize=unlimited    -- 无限大小
)
to filegroup GroupTwo

alter database Test add file
(
    name=N'ThreeFile',
    filename=N'D:\DataDB\ThreeFile.mdf',
    size=3MB,
    filegrowth=10%,
    maxsize=unlimited    -- 无限大小
)
to filegroup GroupThree

alter database Test add file
(
    name=N'FourFile',
    filename=N'D:\DataDB\FourFile.mdf',
    size=3MB,
    filegrowth=10%,
    maxsize=unlimited    -- 无限大小
)
to filegroup GroupFour

alter 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)
begin
    insert into US_Info(Name,CreateTime)
    values('名称'+convert(nvarchar,@I),Convert(nvarchar,GETDATE(),121))
    set @I=@I+1
end

select * 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_back

select * 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)
begin
    insert into UserInfo(U_No,U_Name,U_Pwd)
    values('demo'+convert(nvarchar,@I),'demo'+convert(nvarchar,@I),'40D1C69C7B86064EA140C13CE8ED0E15')
    set @I=@I+1
end

select * 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_right
            WHEN 1 THEN 'RIGHT'
            ELSE 'LEFT' END    AS Range,
      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.partition_schemes           AS ps
      ON ps.data_space_id = ds.data_space_id
JOIN sys.partition_functions         AS pf
      ON pf.function_id = ps.function_id
JOIN sys.destination_data_spaces     AS dds2
      ON dds2.partition_scheme_id = ps.data_space_id AND dds2.destination_id = p.partition_number
JOIN sys.filegroups                  AS fg
      ON fg.data_space_id = dds2.data_space_id
LEFT JOIN sys.partition_range_values AS prv_left
      ON ps.function_id = prv_left.function_id AND prv_left.boundary_id = p.partition_number - 1
LEFT JOIN sys.partition_range_values AS prv_right
      ON ps.function_id = prv_right.function_id AND prv_right.boundary_id = p.partition_number
WHERE OBJECTPROPERTY(p.object_id, 'ISMSShipped') = 0
UNION ALL
SELECT
      OBJECT_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

来源及参考:https://www.cnblogs.com/Brambling/p/6766482.html

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

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

SQL Server表分区(水平分区及垂直分区)的更多相关文章

  1. SQL Server 表分区之水平表分区

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

  2. SQL Server表分区-水平分区

    SQL Server表分区,sql server水平分区 转自:http://www.cnblogs.com/knowledgesea/p/3696912.html  根据时间的,直接上T-SQL代码 ...

  3. SQL Server表分区的NULL值问题

    SQL Server表分区的NULL值问题 SQL Server表分区只支持range分区这一种类型,但是本人觉得已经够用了 虽然MySQL支持四种分区类型:RANGE分区.LIST分区.HASH分区 ...

  4. 8、SQL Server 表分区

    什么是表分区?表分区其实就是将一个大表分成若干个小表.表分区可以从物理上将一个大表分成几个小表,但是逻辑上还是一个表.所以当执行插入.更新等操作的时候,不需要我们去判断应该插入或更新到哪个表中.只需要 ...

  5. SQL Server表分区【转】

    转自:http://www.cnblogs.com/knowledgesea/p/3696912.html SQL Server表分区   什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在 ...

  6. SQL Server表分区详解

    原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆 ...

  7. SQL Server 2005/2008/2012中应用分布式分区视图

    自2000版本起,SQL Server企业版中引入分布式分区视图,允许你为分布在不同的SQL 实例的两个或多个水平分区表创建视图. 简要步骤如下:根据Check约束中定义的一组值把大表分割成更小的一些 ...

  8. SqlServer还原数据库时提示:异常终止,不能在此版本的SQL Server中启动,因为它包含分区函数

    场景 在SqlServer Management中进行数据库还原时提示: 数据库不能在此版本的SQL Server中启动,因为它包含分区函数. 点击左下角的查看详细信息 实现 电脑上安装的是SQL S ...

  9. SQL Server 表变量和临时表的区别

    SQL Server 表变量和临时表的区别 一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯 ...

随机推荐

  1. PHP无限极分类,多种方法|很简单,这里说的很详细,其它地方说的很不好懂

    当你学习php无限极分类的时候,大家都觉得一个字"难"我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究.   到网上一搜php无限极分类,很多,但好多都是一 ...

  2. OL/SQL编程练习

    create or replace procedure pr_first is --一个变量 v_a ) := '总有一天我的生命将走到尽头'; --一个常量 c_b constant ) := '而 ...

  3. C#中嵌入互操作类型的含义

    首先说一下它的含义: 1. ”嵌入互操作类型”中的嵌入就是引进.导入的意思,类似于c#中using,c中include的作用,目的是告诉编译器是否要把互操作类型引入. 2. “互操作类型”实际是指一系 ...

  4. cxf的使用及安全校验-02创建简单的客户端接口

    上一篇文章中,我们已经讲了如果简单的创建一个webservice接口 http://www.cnblogs.com/snowstar123/p/3395568.html 现在我们创建一个简单客户端接口 ...

  5. Extjs 3.4 和 web SSH(Ajaxterm)-howge-ChinaUnix博客

    Extjs 3.4 和 web SSH(Ajaxterm)-howge-ChinaUnix博客   Extjs 3.4 和 web SSH(Ajaxterm) 2013-04-07 15:20:17 ...

  6. 数学之美?编程之美?数学 + 编程= unbelievable 美!

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:Rusu 导语 相信大家跟我一样,偶尔会疑惑:曾经年少的时候学习过的那么多的复杂的数学函数,牛逼的化学方程式,各种物理原理.公式,到底有 ...

  7. P1074 靶形数独

    P1074 靶形数独正着搜80分,完全倒置95分,完全倒置后左右再倒置,就会A掉,到时候脑洞要大一些. #include<iostream> #include<cstdio> ...

  8. ios 手机验证码用户注册(倒计时15秒)

    // // ViewController.m // register手机验证码注册 // // Created by zzqqrr on 17/8/28. // Copyright (c) 2017年 ...

  9. 一种简单的ELF加固方法

    介绍一种ELF文件函数粒度的加固方法,可以有效防止对程序的静态分析.这是一种有源码加固方式,需要被加固程序中代码配合.加固流程如下: 1)读取ELF文件头,获取e_phoff和e_phnum2)通过E ...

  10. 20.struts2的数据填充和类型转换.md

    目录 1. struts2的自动填充 2. struts2的对象填充 3. struts2的类型转换器 3.1 类继承关系 3.2 局部转换器 3.3 全局转换器 3.4 注意 1. struts2的 ...