MS SQL表分區(文件組)

定義:表分區其實就是將一個大表分成若干個小表。 表分區可以從物理上將一個大表分成幾個小表,但是邏輯上還是一個表。所以當執行插入、更新等操作的時候,不需要我們去判斷應該插入或更新到哪個表中。只需要插入大表中就可以了。SQL Server會自動的將它放在對應的表中。對於查詢也是一樣,直接查詢大表就可以了。

目的:把數據按照規則存放在不同的文件中,提升查詢速度。

如何創建分區表(假設數據庫名:webDB)

一、創建文件組

其實可以使用默認的primary組,但是爲了更方便管理以及提高運行速度,所以還是應該創建幾個分組。

1、使用SSMS創建文件組

2、使用T-SQL創建文件組

--alter database <數據庫名> add filegroup <文件組名>
alter database webDB add filegroup group2013
alter database webDB add filegroup group2014
alter database webDB add filegroup group2015

二、爲文件組添加數據庫文件

1、使用SSMS添加數據庫文件

2、使用T-SQL添加數據庫文件

複製代碼
複製代碼
--alter database <數據庫名稱> add file <數據標識> to filegroup <文件組名稱>
alter database webDB add file
(
    name='web2013',
    filename='D:\web2013.ndf',
    size=5mb,
    filegrowth=5mb
)
to filegroup group2013
alter database webDB add file
(
    name='web2014',
    filename='D:\web2014.ndf',
    size=5mb,
    filegrowth=5mb
)
to filegroup group2014

alter database webDB add file
(
    name='web2015',
    filename='D:\web2015.ndf',
    size=5mb,
    filegrowth=5mb
)
to filegroup group2015
複製代碼
複製代碼

注意:儘可能的將不同的文件放在不同的硬盤分區裏,或者獨立硬盤中。這樣可以加快SQL Server運行速度。

三、創建分區函數

分區函數用來告訴SQL Server用什麼樣的規則進行分區,這一步必須使用T-SQL腳本來執行了。

複製代碼
複製代碼
create partition function fenqu(datetime) --分區函數名
as range right  --right分區方式 邊界值去左表還是右表
for values ('2014-01-01','2015-01-01') --按這些值來分區 
--group2013 : 2014-01-01 之前的
--group2014 : 2014-01-01 到 2014-12-31的
--group2015 : 2015-01-01 之後的
複製代碼
複製代碼

四、創建分區方案

create partition scheme SchemeFenqu --分區方案名
as partition fenqu    --之前創建的分區函數
to(group2013,group2014,group2015) --跟放的文件組

創建完分區函數和分區方案後可以在存儲中查看

五、創建分區表

複製代碼
複製代碼
create table fenquTable
(
    id int identity(1,1) not null,
    name varchar(20) not null,
    createTime datetime not null
) on SchemeFenqu(createTime) --調用分區方案
複製代碼
複製代碼

注意:不可以使用聚集索引,因爲聚集索引是存在連續的物理地址中的,而表分區是將數據分別存儲在不同表中的。

至此物理上分離的,邏輯上一體的分區表就創建完了。

操作分區表

一、插入數據

複製代碼
複製代碼
--插入測試數據
insert into fenquTable(name,createTime) values ('隔壁老王','2010-01-01')
insert into fenquTable(name,createTime) values ('隔壁老張','2011-01-01')
insert into fenquTable(name,createTime) values ('隔壁老趙','2012-01-01')
insert into fenquTable(name,createTime) values ('隔壁老李','2013-01-01')
insert into fenquTable(name,createTime) values ('老李兒子','2013-10-01')
insert into fenquTable(name,createTime) values ('隔壁老田','2014-01-01')
insert into fenquTable(name,createTime) values ('隔壁老樑','2015-01-01')
insert into fenquTable(name,createTime) values ('老樑姑娘楠楠','2015-10-10')
複製代碼
複製代碼

跟插入普通表沒有任何區別,不用管他放在哪個物理磁盤上。

二、查詢數據

--查詢數據
select * from fenquTable

查詢也是如此,不用考慮哪個磁盤,邏輯上都屬於同一個表,基本上看不出區別。如果需要查看哪條插入到哪個物理的分區表中,可以使用$partition函數查看。

複製代碼
複製代碼
--語法:$partition.分區函數名(表達式)
--查看該表達式下有多少數據
select $partition.fenqu('2015-01-01') --返回3

--查看分區表明細
select * from fenquTable where $partition.fenqu(createTime)=1
select * from fenquTable where $partition.fenqu(createTime)=2
select * from fenquTable where $partition.fenqu(createTime)=3

--查看分區表中的記錄數
select $partition.fenqu(createTime) as 分區 ,count(id) from fenquTable 
group by $partition.fenqu(createTime)
複製代碼
複製代碼

三、修改數據

複製代碼
複製代碼
select $partition.fenqu(createTime) as 分區,count(id) as 數量 from fenquTable
group by $partition.fenqu(createTime)
--分區    數量
--1            5
--2            1
--3            2

update fenquTable set createTime ='2015-01-01' where id = 1

select $partition.fenqu(createTime) as 分區,count(id) as 數量 from fenquTable
group by $partition.fenqu(createTime)
--分區    數量
--1            4
--2            1
--3            3
複製代碼
複製代碼

可以明顯看到,跟普通修改沒有區別,SQL Server可以自動幫我們重新劃分分區,將數據從第一個分區移動到第五個分區中。

普通錶轉分區表

上面介紹瞭如何在創建表的時候進行分區,但往往我們需要的是將現有的普通表在數據保留的情況下進行分區。

普通表一般都有主鍵,同時還是聚集索引。分區是以某個字段爲條件進行的,而除了這個字段其他字段是不可以創建聚集索引的。所以需要先刪除表中的聚集索引,再新建一個聚集索引。

複製代碼
複製代碼
--刪除主鍵,自動同時刪除索引
alter table newTable drop constraint PK_newTable 

--創建主鍵,但不創建聚集索引
alter table newTable add constraint PK_newTable
primary key nonclustered --非聚集
(
    id asc
) on [primary]

--然後給我們親愛的時間創建一個聚集索引
create clustered index CT_newTable on newTable(createTime)
on schemeFenqu(createTime) --並調用分區方案

--然後再查詢分區,發現數據保留情況下,已經將數據按規則進行分區了
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
複製代碼
複製代碼

添加分區

向上面只分了3個區,而15年以後的都存在第三個分區中,到16年還是會存在這個分區中,這時候需要再新加一個16年的分區。

添加新的分區意味着要新建一個文件組和文件來存放這個分區表,然後在分區方案中用到這個文件組,最後再修改一下分區函數的規則即可。文件組和分區數量要保持一致。

複製代碼
複製代碼
--創建文件組
alter database webDB add filegroup group2016

--添加數據庫文件
alter database webDB add file
(
    name='web2016',
    filename='D:\web2016.ndf',
    size=5mb,
    filegrowth=5mb
)
to filegroup group2016

--修改分區方案
alter partition scheme SchemeFenqu
next used group2016

--修改分區函數
alter partition function fenqu()
split range('2016-01-01')

--添加2016年數據
insert into newTable (name,createTime) values ('16年小明','2016-03-05')

--查看分區及統計
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
複製代碼
複製代碼

刪除分區

刪除分區就是將分區函數中多餘的邊界值刪除。

如:2013,2014,2015,2016 現在需要將13年和14年進行合併,刪除13年的分區。

複製代碼
複製代碼
--查看分區及統計
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
--分區    數量
--1        4
--2        1
--3        3
--4        1

--刪掉該邊界值
alter partition function fenqu() merge range('2014-01-01')

--再次查詢
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
--分區    數量
--1        5
--2        3
--3        1
複製代碼
複製代碼

拆分分區

有的時候某一分區中數據量過大,需要將這個分區再次拆分爲多個分區,以加快訪問速度。

拆分分區的操作其實與添加分區類似,首先要添加文件組、文件、修改分區方案、修改分區函數(新增一個邊界值)。

如:2014,2015,2015年6月份以上一個 6月份一下一個。

複製代碼
複製代碼
--查看分區及統計
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
--分區        數量
--1            5
--2            3
--3            1

--創建文件組
alter database webDB add filegroup group2014_2015

--添加數據庫文件
alter database webDB add file
(
    name='web2014_2015',
    filename='D:\web2014_2015.ndf',
    size=5mb,
    filegrowth=5mb
)
to filegroup group2014_2015

--修改分區方案
alter partition scheme SchemeFenqu
next used group2014_2015

--修改分區函數
alter partition function fenqu()
split range('2015-06-01')

--查看分區及統計
select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
--分區        數量
--1            5
--2            2
--3            1
--4            1
複製代碼
複製代碼

分區錶轉普通表

複製代碼
複製代碼
--修改分區函數 將邊界值都刪除
alter partition function fenqu()
merge range('2013-01-01')
alter partition function fenqu()
merge range('2014-01-01')
alter partition function fenqu()
merge range('2015-01-01')
alter partition function fenqu()
merge range('2015-06-01')

select $partition.fenqu(createTime) as 分區,count(id) as 數量
from newTable group by $partition.fenqu(createTime)
--這時只有一個分區了
--分區    數量
--1        9
複製代碼
複製代碼

這樣雖然只有一個分區了,但是查看數據表存儲位置,是否進行分區:True,分區數1.

--重新建立聚集索引
create clustered index CT_newTable on newTable(createTime)
    with(drop_existing=on) --如果存在則刪除
on [primary]

刪除分區索引後,重新建立聚集索引,這時再此查看數據表的存儲位置,是否分區:Flase。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章