SqlServer數據庫分區分表實例分享(有詳細代碼和解釋)

數據庫單表數據量太大可能會致使數據庫的查詢速度大大降低(感受都是千萬級以上的數據表了),能夠採起分區分表將大表分爲小表解決(固然這只是其中一種方法),好比數據按月、按年分表,最後可使用視圖將小表從新併爲總的虛擬表,其實並不影響上層程序的使用(程序也許都不知道分表了)。數據庫

主要步驟:

一、新建文件組,將數據表文件保存路徑指向相應文件組(應將文件組和文件放入不一樣的磁盤中,甚至不一樣服務器造成分佈式數據庫,由於數據的讀取瓶頸很大程度在於磁盤的的讀寫速度,多個磁盤存放一個表能夠負載均衡)express

二、設置分區函數(聲明分區的標準)數組

三、設置分區方案(即哪些區域使用哪一個分區函數,造成完整的分區方案)服務器

四、給新表或現有表設置分區方案併發

五、創建視圖負載均衡

詳細步驟(看需求可選):

1、數據庫狀態備份和恢復

USE master
-- 備份
BACKUP DATABASE AdventureWorks
    TO DISK = 'AdventureWorks.bak'
    WITH FORMAT
 
---- 恢復
RESTORE DATABASE AdventureWorks
    FROM DISK = 'AdventureWorks.bak'
    WITH REPLACE
GO

2、文件組和文件操做

添加文件組

USE [master]
GO
ALTER DATABASE ZHH ADD FILEGROUP [文件組名稱]
Go

添加文件並把其指向指定文件組

USE master;
GO
ALTER DATABASE 數據庫名
ADD FILE(
NAME=N'文件名',
FILENAME='存放路徑', //如:E:\201109.NDF(精確到文件名)文件組存放與不一樣磁盤能夠提升IO讀寫效率(多個磁頭併發)
SIZE=3MB,
MAXSIZE=100MB,
FILEGROWTH=5MB
)TO FILEGROUP [文件組名]
Go

修改文件(可選)

USE master;
GO
ALTER DATABASE 數據庫名
MODIFY FILE
(NAME = 文件名,
SIZE = 20MB);   //能夠修改全部屬性,列舉便可
GO

刪除文件(可選)

ALTER DATABASE 數據庫名 REMOVE FILE [文件組名] 

3、分區函數和分區方案

分區函數

用於規範如何分區的標準,如已哪列進行爲標準分區、分區的方式(按時間、ID等)、分區的具體界限(通常來講,界限指標數要比分區數少1,一刀則有兩段)分佈式

USE 數據庫名   
GO
CREATE PARTITION FUNCTION 分區函數名 (指標列的數據類型)   //如:datetime、int
AS RANGE RIGHT   //右邊界切分,默認爲LEFT
FOR VALUES (劃分界限)  //如時間劃分('2003/01/01', '2004/01/01'),兩個時間界限可劃分出三個分區
GO

分區方案

用於將已經創建好的分區函數組織成完整的方案,爲每一個分區分配存儲位置函數

Use 數據庫名
go
create  partition  scheme 分區方案名
as partition  分區函數
to(文件組1,文件組2,文件組3,...) //注意分區數要與實際分區一致
go

在原有的基礎上添加分區(可選)

use 數據庫名
go
alter partition scheme ps_OrderDate  next used [FG4]    //修改分區方案ps_OrderDate,定義新新分區使用FG4文件組
alter partition function pf_OrderDate() split range('2005/01/01')  //修改分區函數pf_OrderDate,在末尾添加界限'2005/01/01'
go

爲現有表設置分區方案(可選)

//爲AutoBench表的InsertTime列建立新彙集索引,並綁定Scheme_DateTime分區方案
CREATE CLUSTERED INDEX IX_CreateDate ON AutoBench (InsertTime)
ON Scheme_DateTime (InsertTime)

注:如原來主鍵有聚衆索引要將其改成非彙集索引,纔可添加新聚衆索引測試

//刪除原主鍵上的彙集索引PK_Product
ALTER TABLE Product DROP CONSTRAINT PK_Product

//從新建立主鍵非彙集索引PK_Product
ALTER TABLE Product ADD CONSTRAINT PK_Product PRIMARY KEY NONCLUSTERED (ProductID ASC)

上面語句也可直接在索引屬性中將彙集改成非彙集spa

爲新建表設置分區方案(可選)

//建立表格Order,並設置Scheme_DateTime分區方案,指標列爲OrderDate
CREATE TABLE [Order]
(
    OrderID INT IDENTITY(1,1) NOT NULL,
    UserID INT NOT NULL,
    TotalAmount DECIMAL(18,2) NULL,
    OrderDate DATETIME NOT NULL
) ON Scheme_DateTime (OrderDate)
查詢分區數據

4、其餘操做

查詢分區數據

$partition函數--爲任何指定的分區函數返回分區號,一組分區列值將映射到該分區號中

語法: [ database_name. ] $PARTITION.partition_function_name(expression)

參數: database_name 包含分區函數的數據庫的名稱。

partition_function_name 對其應用一組分區列值的任何現有分區函數的名稱。

expression 其數據類型必須匹配或可隱式轉換爲其對應分區列數據類型的表達式。 expression 也能夠是當前參與partition_function_name 的分區列的名稱。

返回類型: int (分區號)

//篩選使用Function_DateTime做爲分區函數的AutoBench表,以InsertTime做爲指標列的第二個分區的全部數據
select * from AutoBench WHERE $PARTITION.Function_DateTime(InsertTime) = 2

合併分區

//刪除Sales數據庫下的分區函數pf_OrderDate中的'2003/01/01'界限,以次界限劃分的兩個分區合併,分區號一次減1
use Sales
go
alter partition function pf_OrderDate() merge range('2003/01/01')
go

查看系統視圖

select * from sys.partition_functions   //分區函數
select * from sys.partition_range_values    //分區方案
select * from sys.partition_schemes     //邊界值點

5、自動分區

能夠採用SQL Server代理中的做業按期自動執行分區腳本,實現自動分區(如每個月結束自動執行按月分區的操做)

自動分區測試腳本

DECLARE 
    @fileGroupName VARCHAR(20),    --文件組名(格式爲:FG+@Month)
    @fileName VARCHAR(20),    --文件名(格式爲:F+@Month)
    @filePath VARCHAR(100),        --文件存放路徑(格式爲:存放目錄路徑+@fileName.ndf)
    @dataBaseName VARCHAR(20),    --數據庫名
    @Month VARCHAR(10),        --當前時間年月(格式爲:yyyymm)
    @schemeName VARCHAR(20),    --分區方案名
    @partFunctionName VARCHAR(20),    --分區函數名
    @limit VARCHAR(10)    --分區界限(以時間分區則爲時間字符串,格式爲:mm/dd/yyyy)

SET @fileGroupName='FG201805'
SET @Month=CONVERT(varchar(10),GETDATE(),112)
SET @fileName=N'F201805'
SET @filePath='C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\F201805.ndf'
SET @dataBaseName='Chassis'
SET @schemeName='Scheme_DateTime'
SET @partFunctionName='Function_DateTime'
SET @limit=CONVERT(varchar(10),GETDATE(),101) 

--語句要指明須要操做的數據庫
if exists(select * from Chassis.sys.filegroups where name=@fileGroupName)
    begin
        print '文件組存在,不需添加'
    end
else
    begin
        exec('ALTER DATABASE '+@dataBaseName+' ADD FILEGROUP ['+@fileGroupName+']')
        print '新增文件組'+@fileGroupName
    end

if exists(select * from Chassis.sys.database_files where [state]=0 and (name=@fileName or physical_name=@filePath))
    begin
        print 'ndf文件存在,不需添加'
    end
else
    begin
        exec('ALTER DATABASE '+@dataBaseName+' ADD FILE(NAME ='''+@fileName+''',FILENAME = '''+@filePath+''')TO FILEGROUP ['+@fileGroupName+']')
        print '添加文件'+@fileName+'至文件組'+@fileGroupName
    end

if exists(select * from sys.partition_schemes where name=@schemeName)
    begin
        exec('alter partition scheme '+@schemeName+' next used ['+@fileGroupName+']')
        print '修改分區方案,指定下一分區的文件組'
    end
else
    begin
        print '分區方案不存在'
    end

if exists(select * from sys.partition_range_values where function_id=(select function_id from sys.partition_functions where name=@partFunctionName))
    begin
        if exists(select * from sys.partition_range_values where function_id=(select function_id from sys.partition_schemes where name='Scheme_DateTime') and value=CONVERT(datetime,''+@limit+'',101))
            begin
                print '界限已存在'
            end
        else
            begin
                exec('alter partition function '+@partFunctionName+'() split range('''+@limit+''')')
                print '修改分區函數,添加劃分界限爲:'+@limit
            end
    end
else
    begin
        print '分區函數不存在'
    end

這只是本人的測試腳本,僅供參考~ 若有錯漏請大佬指導

相關文章
相關標籤/搜索