一. ???創(chuàng)建分區(qū)文件組/文件
--創(chuàng)建分區(qū)文件組
alter database test add filegroup test2015
alter database test add filegroup test2016
alter database test add filegroup test2017
alter database test add filegroup test2018
--創(chuàng)建分區(qū)文件
alter database test
add file(name='test2015'
,filename='D:\DB\testPartion\test2015.ndf'
,size=1mb
,filegrowth=1mb)
to filegroup test2015;
alter database test
add file(name='test2016'
,filename='D:\DB\testPartion\test2016.ndf'
,size=1mb
,filegrowth=1mb)
to filegroup test2016;
alter database test
add file(name=N'test2017'
,filename=N'D:\DB\testPartion\test2017.ndf'
,size=1mb
,filegrowth=1mb)
to filegroup test2017
alter database test
add file(name=N'test2018'
,filename=N'D:\DB\testPartion\test2018.ndf'
,size=1mb
,filegrowth=1mb)
to filegroup test2018
二. ???創(chuàng)建分區(qū)函數(shù)
--創(chuàng)建分區(qū)函數(shù)
create partition function f_TestDate(datetime)
as range right for values('2016-01-01','2017-01-01','2018-01-01')
注意:
1.????????F_TestDate 為分區(qū)函數(shù)名,分區(qū)的字段是datetime類型
2.????????Right 表示該分區(qū)包含右邊界值,上面分區(qū)函數(shù)會把數(shù)據(jù)分為
小于2016.1.1
大于等于2016.1.1 且小于2017.1.1
大于等于2017.1.1 且小于2018.1.1
大于等于2018.1.1
四個分區(qū),若把right換為left,則分區(qū)變?yōu)?/p>
小于等于2016.1.1
大于2016.1.1 且小于等于2017.1.1
大于2017.1.1 且小于等于2018.1.1
大于2018.1.1
三. ???創(chuàng)建分區(qū)方案
--創(chuàng)建分區(qū)方案
create partition scheme s_TestDate
as partition f_TestDate to (test2015,test2016,test2017,test2018)
注意:
1.????????分區(qū)方案是建立在分區(qū)函數(shù)的基礎(chǔ)上的,所以先建立分區(qū)函數(shù),再建立分區(qū)方案
2.????????分區(qū)個數(shù)比分區(qū)邊界值多1
3.????????本分區(qū)方案每個分區(qū)建在一個文件組上,當(dāng)然也可以把所有分區(qū)建立在一個文件組上
--創(chuàng)建分區(qū)方案,所有分區(qū)均建立在主文件組上
create partition scheme s_TestDate
as partition f_TestDate all to ([primary])
兩種方案的優(yōu)劣待續(xù)……
四. ???創(chuàng)建分區(qū)表
4.1??新建分區(qū)表
create table tradelog
(
ID int,
productID int,
tradedate datetime
) on s_TestDate(tradedate)
注:創(chuàng)建分區(qū)表,用的是s_TestDate分區(qū)方案名稱
4.2??對已有表分區(qū)
若表上沒有聚集索引,可以通過創(chuàng)建聚集索引,對表進(jìn)行分區(qū)
CREATE CLUSTERED INDEX [CLI_tn_TestDate] ON [dbo].[tradelog_noClusterIndex]
(
[tradedate]
) ON [s_TestDate]([tradedate])
--如果不需要聚集索引,刪除聚集索引
DROP INDEX [CLI_tn_TestDate] ON [dbo].[tradelog_noClusterIndex]
若表上已有聚集索引,刪除聚集索引,再通過上面腳本重建聚集索引。或者通過WITH(DROP_EXISTING=ON)重建聚集索引,腳本如下:
CREATE CLUSTERED INDEX [CLI_tn_TestDate] ON [dbo].[tradelog_noClusterIndex]
(
[tradedate]
)WITH (DROP_EXISTING = ON) ON [s_TestDate]([tradedate])
五. ???增加分區(qū)
增加分區(qū)的方法是將某個現(xiàn)有的分區(qū)“拆分”為兩個分區(qū)并重新定義新分區(qū)的邊界。
--向分區(qū)表插入1000W行數(shù)據(jù)
DECLARE @max AS INT, @rc AS INT;?
SET @max = 10000000;?
SET @rc = 1;?
INSERT INTO tradelog(id,productID,tradedate) VALUES(1,1,'2014-01-01');?
WHILE @rc * 2 <= @max?
BEGIN?
? ? INSERT INTO dbo.tradelog(id,productID,tradedate) SELECT id + @rc,id + @rc+1,DATEADD(mi,id,tradedate) FROM dbo.tradelog;?
? ? SET @rc = @rc * 2;?
END?
INSERT INTO dbo.tradelog (id,productID,tradedate)
SELECT id + @rc,id + @rc+1,DATEADD(mi,id,tradedate) FROM dbo.tradelog WHERE id + @rc <= @max;?
go?
--查看分區(qū)表的現(xiàn)狀
;with cte as
(select
object_id
,OBJECT_NAME(i.object_id) tableName
,i.index_id
,dds.partition_scheme_id
,dds.destination_id as partition_number
,fg.groupid
,fg.groupname
,f.fileid
,f.name
,f.filename
--,p.partition_id
--,p.rows
from sys.destination_data_spaces dds,sys.indexes i,sys.sysfilegroups fg,sys.sysfiles f
where dds.partition_scheme_id=i.data_space_id
and dds.data_space_id=fg.groupid
and fg.groupid=f.groupid
)
,cte1 as(
select
ps.data_space_id as partition_scheme_id
,ps.name partiton_schemes_name
,pf.name partition_function_name
,pf.function_id
--,prv.value AS BoundaryValue
from sys.partition_schemes ps ,sys.partition_functions pf
where ps.function_id=pf.function_id
--and pf.function_id=prv.function_id
)
select cte.tableName,cte.groupname,cte.name,cte.filename
,cte.partition_number,cte1.partiton_schemes_name,cte1.partition_function_name,p.rows
,prv.boundary_id,prv.value BoundaryValue
from cte
inner join cte1 on cte.partition_scheme_id=cte1 .partition_scheme_id
left join sys.partition_range_values prv on cte1.function_id=prv.function_id and cte.partition_number=prv.boundary_id
left join sys.partitions? p on cte.object_id=p.object_id and cte.index_id=p.index_id and cte.partition_number=p.partition_number
where
cte.object_id=OBJECT_ID('dbo.tradelog','U')
可以看到tradelog表按交易時間列分為4區(qū),分區(qū)邊界值為16、17、18三年的1月1日,其中
16年以前的數(shù)據(jù)存在文件test2015上
16年數(shù)據(jù)存在文件test2016上
17年數(shù)據(jù)存在文件test2017上
18年及以后的數(shù)據(jù)存在文件test2018上
現(xiàn)在增加一個分區(qū),將2019以后的數(shù)據(jù)分開,或者說將原4分區(qū)以2019年1月1日為分區(qū)邊界拆分為兩個分區(qū),具體腳本如下:
--創(chuàng)建新分區(qū)文件組
alter database test add filegroup test2019
--創(chuàng)建新分區(qū)文件
alter database test
add file(name='test2019'
,filename='D:\DB\testPartion\test2019.ndf'
,size=1mb
,filegrowth=1mb)
to filegroup test2019;
alter partition scheme s_TestDate
next used test2019
alter partition function f_TestDate()
split range('2019-01-01 0:00:00')
重新執(zhí)行分區(qū)狀態(tài)查詢腳本,結(jié)果如下圖:
可以看到,源第4分區(qū)被拆分為兩個分區(qū),并且2019年以后的數(shù)據(jù)被移動到新的文件test2019上。
可以有這樣一個結(jié)論,新增分區(qū)后,新增的邊界值,到下一個分區(qū)邊界值之間的數(shù)據(jù),將被移動到新的文件上,無論是拆分第1個分區(qū),還是拆分中間的某個分區(qū)(如拆分第4個分區(qū)),如下圖:
六. ???合并分區(qū)
減少分區(qū)的方法是將兩個分區(qū)的邊界“合并”成一個。 減少分區(qū)操作將重新填充一個分區(qū)而不對另一個分區(qū)進(jìn)行分配。
--分區(qū)合并
alter partition function f_TestDate()
merge range('2018-07-01 0:00:00')
分區(qū)合并的數(shù)據(jù)移動方向剛好和增加分區(qū)的方向相反,分區(qū)合并后,將合并分界點(diǎn)的后一個分區(qū)數(shù)據(jù)移動到前一個分區(qū)的文件中。這個結(jié)論在數(shù)據(jù)自動歸檔中將極為有用,因?yàn)閿?shù)據(jù)歸檔最后一步是將合并后的空文件、文件組回收,這樣就可以確定回收的文件名
七. ???分區(qū)數(shù)據(jù)移到普通表
create table tradelog_partition1
(
ID int,
productID int,
tradedate datetime
) on test2015
alter table tradelog switch partition 1 to tradelog_partition1
把分區(qū)表的某個分區(qū)數(shù)據(jù)轉(zhuǎn)移到普通表,要求
1.??????普通表必須和對應(yīng)的分區(qū)在同一個文件組下
2.??????普通表和分區(qū)表結(jié)構(gòu)相同,包括字段、數(shù)據(jù)類型、數(shù)據(jù)長度、索引等
分區(qū)表上在tradedate上有聚集索引,但普通表tradelog_partition1上沒有建聚集索引,執(zhí)行上述腳本就會報如下錯誤:
八. ???普通表數(shù)據(jù)移到某一分區(qū)
alter table tradelog_partition1 switch to tradelog partition 1
在tradelog_partition1的tradedate上創(chuàng)建聚集索引,重新執(zhí)行上面的腳本,又報了如下錯誤
What happen??這是因?yàn)榉謪^(qū)1上有CHECK日期要在2014到2016之間,而tradelog_partition1上沒有這個檢查,所以,在表上加上如下檢查:
ALTER TABLE dbo.tradelog_partition1
ADD CONSTRAINT TradeDate_Switch_CHECK CHECK
(TradeDate >= CONVERT(DATE,'2014-01-01') AND TradeDate < CONVERT(DATE,'2016-01-01')
? ? ? ? ? ? AND TradeDate IS NOT NULL);
GO
再執(zhí)行移動數(shù)據(jù),數(shù)據(jù)又重新移回到分區(qū)1中。
————————————————
版權(quán)聲明:本文為CSDN博主「三空道人」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zhoujunah/article/details/79744590