http://imPRove.dk/orcamdf-now-supports-databases-with-multiple-data-files/
OrcaMDF 其中一個(gè)最新特性是支持多數(shù)據(jù)文件的數(shù)據(jù)庫(kù)。這在解析上面需要作出相關(guān)的小改變,實(shí)際上大部分都是bug 修復(fù)代碼
由于之前只支持單個(gè)數(shù)據(jù)文件而引起的。然而這確實(shí)需要一些重大的重構(gòu)而離開(kāi)MdfFile 的主入口點(diǎn),現(xiàn)在使用數(shù)據(jù)庫(kù)封裝類(lèi),封裝一個(gè)數(shù)據(jù)文件變量
分配比例填充
OrcaMDF 支持標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)表的比例填充架構(gòu),這個(gè)數(shù)據(jù)庫(kù)表除了有mdf文件之外還有ndf文件,而這些文件都在主文件組里,例如,你可能會(huì)創(chuàng)建以下數(shù)據(jù)文件或者架構(gòu)
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% )GOUSE SampleDatabaseGOCREATE TABLE MyTable( A int identity, B uniqueidentifier default(newid()), C char(6000))GOINSERT INTO MyTable DEFAULT VALUESGO 100
這會(huì)引起MyTable 按比例填充三個(gè)數(shù)據(jù)文件(C列的作用為了讓SQLSERVER分配100個(gè)頁(yè)面來(lái)裝載數(shù)據(jù),好讓填滿(mǎn)三個(gè)數(shù)據(jù)文件)
為了解析這種情況,我們需要做下面的工作
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);}
運(yùn)行之后的結(jié)果是
大家注意看:
A(4個(gè)字節(jié))+B(16個(gè)字節(jié))+C(6000個(gè)字節(jié))=6020字節(jié)
剛好一條記錄一頁(yè),下面說(shuō)到,SQLSERVER分配完了一個(gè)區(qū)之后,一個(gè)區(qū)8個(gè)頁(yè)面,當(dāng)一個(gè)區(qū)分配完畢之后,SQLSERVER
會(huì)轉(zhuǎn)到SampleDatabase_Data2.ndf數(shù)據(jù)文件繼續(xù)分配頁(yè)面,分配的值是9~16,一個(gè)區(qū)分配完畢之后又到
SampleDatabase_Data3.ndf數(shù)據(jù)文件繼續(xù)分配頁(yè)面,分配的值是17~24
自增值會(huì)一直到100,注意到A列有間隔,這是由于一個(gè)事實(shí)我們?cè)诿總€(gè)數(shù)據(jù)文件的一個(gè)區(qū)里面以循環(huán)賽的方式來(lái)分配。
ID1~8在第一個(gè)數(shù)據(jù)文件,9~16在第二個(gè)數(shù)據(jù)文件最后17~24在第三個(gè)數(shù)據(jù)文件。由于這一點(diǎn),頁(yè)面25~32分配在第一個(gè)數(shù)據(jù)文件,一直這樣下去
由于是堆表,我們使用文件分配順序掃描,這導(dǎo)致我們獲得結(jié)果1~8,25~32,49~56,73~80,97~100 全部都是從第一個(gè)文件開(kāi)始,然后9~16,33~40
從第二個(gè)數(shù)據(jù)文件里讀取然后到最后一個(gè)數(shù)據(jù)文件的剩余頁(yè)面。想一下這是不是很怪,好吧,SQLSERVER里面也是完全一樣的
不理解的童鞋可以看一下這篇文章《SQLSERVER中的ALLOCATION SCAN和RANGE SCAN》或者
《Microsoft SQL Server 2008技術(shù)內(nèi)幕:T-SQL查詢(xún) 筆記》里面有相關(guān)介紹
文件組支持
OrcaMDF 也支持使用文件組,包括按比例分配填充在一個(gè)單獨(dú)的 文件組里,舉個(gè)例子,你可能創(chuàng)建下面的數(shù)據(jù)庫(kù)和架構(gòu)
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% )GOALTER DATABASE [SampleDatabase]ADD FILEGROUP [SecondFilegroup]GOALTER 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]GOUSE SampleDatabaseGOCREATE TABLE MyTable( A float default(rand()), B datetime default(getdate()), C uniqueidentifier default(newid()), D char(5000)) ON [SecondFilegroup]GOINSERT INTO MyTable DEFAULT VALUESGO 100
這將會(huì)引起MyTable去按比例填充分配在第二和第三個(gè)數(shù)據(jù)文件之間(D列用來(lái)占位置,確保讓SQLSERVER分配100個(gè)頁(yè)面來(lái)裝載數(shù)據(jù),好讓對(duì)文件組里的兩個(gè)數(shù)據(jù)文件進(jìn)行
分配填充)數(shù)據(jù)只會(huì)分別對(duì)第二和第三數(shù)據(jù)文件進(jìn)行填充而主數(shù)據(jù)文件不受影響
跟先前的例子的解釋一樣,結(jié)果如下
將會(huì)一直到100
第八篇完
新聞熱點(diǎn)
疑難解答
圖片精選