解剖SQLSERVER 第八篇 OrcaMDF 現在支持多數據文件的數據庫(譯)
http://improve.dk/orcamdf-now-supports-databases-with-multiple-data-files/
OrcaMDF 其中一個最新特性是支持多數據文件的數據庫。這在解析上面需要作出相關的小改變,實際上大部分都是bug 修復代碼
由于之前只支持單個數據文件而引起的。然而這確實需要一些重大的重構而離開MdfFile 的主入口點,現在使用數據庫封裝類,封裝一個數據文件變量
分配比例填充
OrcaMDF 支持標準的數據庫表的比例填充架構,這個數據庫表除了有mdf文件之外還有ndf文件,而這些文件都在主文件組里,例如,你可能會創建以下數據文件或者架構
CREATE DATABASE [SampleDatabase] ON PRIMARY ( NAME = N'SampleDatabase_Data1', FILENAME = N'C:SampleDatabase_Data1.mdf', SIZE = 3072KB, FILEGROWTH = 1024KB ), ( NAME = N'SampleDatabase_Data2', FILENAME = N'C:SampleDatabase_Data2.ndf', SIZE = 3072KB, FILEGROWTH = 1024KB ), ( NAME = N'SampleDatabase_Data3', FILENAME = N'C:SampleDatabase_Data3.ndf', SIZE = 3072KB, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'SampleDatabase_log', FILENAME = N'C:SampleDatabase_log.ldf', SIZE = 3072KB, FILEGROWTH = 10% ) GO USE SampleDatabase GO CREATE TABLE MyTable ( A int identity, B uniqueidentifier default(newid()), C char(6000) ) GO INSERT INTO MyTable DEFAULT VALUES GO 100
這會引起MyTable 按比例填充三個數據文件(C列的作用為了讓SQLSERVER分配100個頁面來裝載數據,好讓填滿三個數據文件)
為了解析這種情況,我們需要做下面的工作
var files = new[] { @"C:SampleDatabase_Data1.mdf", @"C:SampleDatabase_Data2.ndf", @"C:SampleDatabase_Data3.ndf" }; using (var db = new Database(files)) { var scanner = new DataScanner(db); var result = scanner.ScanTable("MyTable"); EntityPrinter.Print(result); }
運行之后的結果是
大家注意看:
A(4個字節)+B(16個字節)+C(6000個字節)=6020字節
剛好一條記錄一頁,下面說到,SQLSERVER分配完了一個區之后,一個區8個頁面,當一個區分配完畢之后,SQLSERVER
會轉到SampleDatabase_Data2.ndf數據文件繼續分配頁面,分配的值是9~16,一個區分配完畢之后又到
SampleDatabase_Data3.ndf數據文件繼續分配頁面,分配的值是17~24
自增值會一直到100,注意到A列有間隔,這是由于一個事實我們在每個數據文件的一個區里面以循環賽的方式來分配。
ID1~8在第一個數據文件,9~16在第二個數據文件最后17~24在第三個數據文件。由于這一點,頁面25~32分配在第一個數據文件,一直這樣下去
由于是堆表,我們使用文件分配順序掃描,這導致我們獲得結果1~8,25~32,49~56,73~80,97~100 全部都是從第一個文件開始,然后9~16,33~40
從第二個數據文件里讀取然后到最后一個數據文件的剩余頁面。想一下這是不是很怪,好吧,SQLSERVER里面也是完全一樣的
不理解的童鞋可以看一下這篇文章《SQLSERVER中的ALLOCATION SCAN和RANGE SCAN》或者
《Microsoft SQL Server 2008技術內幕:T-SQL查詢 筆記》里面有相關介紹
文件組支持
OrcaMDF 也支持使用文件組,包括按比例分配填充在一個單獨的 文件組里,舉個例子,你可能創建下面的數據庫和架構
CREATE DATABASE [SampleDatabase] ON PRIMARY ( NAME = N'SampleDatabase_Data1', FILENAME = N'C:SampleDatabase_Data1.mdf', SIZE = 3072KB, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'SampleDatabase_log', FILENAME = N'C:SampleDatabase_log.ldf', SIZE = 3072KB, FILEGROWTH = 10% ) GO ALTER DATABASE [SampleDatabase] ADD FILEGROUP [SecondFilegroup] GO ALTER DATABASE [SampleDatabase] ADD FILE ( NAME = N'SampleDatabase_Data2', FILENAME = N'C:SampleDatabase_Data2.ndf', SIZE = 3072KB, FILEGROWTH = 1024KB ), ( NAME = N'SampleDatabase_Data3', FILENAME = N'C:SampleDatabase_Data3.ndf', SIZE = 3072KB, FILEGROWTH = 1024KB ) TO FILEGROUP [SecondFilegroup] GO USE SampleDatabase GO CREATE TABLE MyTable ( A float default(rand()), B datetime default(getdate()), C uniqueidentifier default(newid()), D char(5000) ) ON [SecondFilegroup] GO INSERT INTO MyTable DEFAULT VALUES GO 100
這將會引起MyTable去按比例填充分配在第二和第三個數據文件之間(D列用來占位置,確保讓SQLSERVER分配100個頁面來裝載數據,好讓對文件組里的兩個數據文件進行
分配填充)數據只會分別對第二和第三數據文件進行填充而主數據文件不受影響
跟先前的例子的解釋一樣,結果如下
將會一直到100
第八篇完
文章列表