選擇數據庫分割方式
分割是將表分散到可能位于不同的數據庫或者服務器上的多個子表中,這樣做的目的是改善讀寫性能。分割通常是在表的級別上完成,還有當一組相關的表分散了的時候,也會考慮數據庫的分割。表通常是橫向或者縱向分割的。以下的文章可以幫助你理解那些分割方式,并且決定何時使用哪一種方式。
縱向分割改善數據的訪問
在縱向分割的表中,字段從主表中刪除,并且通過一個名為denormalization(反標準化)的進程放置在子表中。這種類型的分割允許你將更多的行放在一個數據庫頁面上,讓表變得狹窄,以利于提高數據訪問的性能。因此,單個的I/O操作會返回更多的行。通過縱向分割你的數據,你必須采用連接(join)的方式來返回被反標準化了的字段。仔細考慮縱向分割對你整體數據訪問模式的影響。
在默認情況下,SQL Server會在數據庫頁面上縱向分割文本和圖像數據類型。使用文本和圖像數據類型創建的字段會存儲在獨立的數據頁面上,與非文本和非圖像字段區別開。通過這種方式,他們可以占用更少的空間,比起你將文本數據存儲在使用varchar數據類型創建的文本數據中。
考慮如下的表:
| Create Table Table1 (PK int not null identity constraint pk primary key, Charcol1 char(10), Charcol2 char(10), Textcol text) |
你可以在每頁上存儲總數為8096/(4+10+10)=338行的數據,忽略每行的額外開銷。如果你用varchar(8000)字段存儲量文本數據,假設你在這個字段中有8KB的數據,那么你就可以在每頁上存儲一行。如果你的查詢的主要內容就是返回文本字段,這個存儲引擎優化會給你帶來大大的好處。如果你的查詢的主要內容是返回文本字段,那么你就會希望使用text in row選項了。text in row表選項將文本數據存儲在一個單個的數據庫頁面上,如果文本的數量少于配置的限制的話。
橫向分割改善整體讀寫性能。
一個橫向定位的表將一些數據行根據某個標準,分散到了不同的表或者數據庫(有時候是不同的服務器)中,這些標準包括主鍵值,日期字段或者位置標識符。
考慮一下,當一個應用程序有10000個用戶都必須訪問同一個服務器上的某個表的時候:你可以預見到在這個表上會產生大量的讀寫沖突。要改善整體的讀性能,你可以考慮縮小表的規模,然后將其分散到10個SQL Server上,然后再將負載均衡分配到這10個服務器上,每個數據庫訪問擁有1000個用戶。這看起來是個不錯的改善性能的方式——但是有以下幾點不足:
存儲利用:與分散到每個節點上的數據同樣的拷貝。
數據分散:你如何保證所有的節點都同步具有同一個數據的拷貝?
數據管理語言同步:你如何保證所有節點上的變化都保持同步?
SQL Server 2005將會提供一個peer-to-peer (P2P)的復制模式,專為在多個服務器上分散統一的數據集合所用,并且保持他們的同步性。一個節點的更新將會復制到拓撲結構內所有其他節點中:當一個節點重新在線,它會以P2P的模式與其他節點中發生的更新同步。這種解決方案的設計目標是將位于不同地理位置的服務器的規模按照比例縮小。
然而,在大多數的橫向分割實現過程中,每個服務器或數據庫都包含數據的子集。在SQL Server 7之前的版本上,這些實現是在應用程序的級別上完成的,在那里調用應用程序根據查詢參數(SARG)來決定訪問那個表。如果表在同一個數據庫內分割,T-SQL邏輯就需要負責分割,這樣每個正確的分割都可以參考或者更新。如果你創建了一個視圖來表示一個完整的結果集,所有的潛在的基本表都需要參考到。
分布式分割視圖
在SQL Server 7中,查詢優化器將會考慮查看執行計劃中的約束。如果你在某個字段上有檢查約束,并且你的SARG參考了這個字段,那么只有正確的分割可以在執行計劃中參考。考慮一個在姓者個字段上有檢查約束的表,如下所示:
CONSTRAINT [CK_Employee] CHECK ([LastName] > 'a' and [LastName] < 'b')
這樣的表只能接受姓以“A”開頭的雇員。那么說你有一個分布式的拓撲結構,包含了26個字母,一個表包含一個字母,那么這些表需要在一個統一擁有這26個表的視圖中參考。
Select * from EmployeeTableView where LastName ='a'
然而,插入、更新和刪除都需要在正確的基本表上執行。在SQL Server 2000種,你需要執行數據管理語言來操作這個視圖,以及參考的正確的基本表。
SQL Server 2005中的分割
SQL Server 2005,于2005年11月發布,引入了一些數據庫分割方面的加強,改善了性能并減小了有關管理分布式數據集的管理負擔。
在SQL Server 之前的版本中,需要你手工創建表來形成分割。在我們上面舉出的例子中,我們需要創建26個表(每個表代表一個字母)來形成雇員的分割。在SQL Server 2005中,你可以創建一個分割函數,然后通過這個函數來分割表,同時SQL Server 還會根據你的范圍函數確定的不同分割內的數據分散。這看起來像是一個表。出于性能的原因,你也許還想要分割的表擴展到多個文件群(可能在不同的磁盤或者陣列中),每一個分割都分配到他自己的文件群中。要做到這一點,你就需要創建一個分割計劃,其中包括了所有的文件群來形成你的分割,然后創建你的表來使用這個分割計劃,代替普通的文件群。
你還可以創建分割索引。在默認情況下,在一個分割上創建的索引可以與分個表使用同一個分割計劃。有關如何使用SQL Server 2005的分割能力的最好資源就是Kimberly Tripp的白皮書。
總結
兩種分割方式都具有其優勢和弱點。SQL Server 2000為你的數據庫分割提供了好幾種選擇:縱向分割通過非標準化和小心使用文本數據類型字段,用于縮小數據行的有效寬度。橫向分割打破了VLDB(超大型數據庫)表,根據范圍形成了小一些代表。SQL Server 7中的查詢優化器也意識到了檢測約束,并且指揮參考符合條件的基本表。另一方面,SQL Server 2000還允許你通過P2P的復制模式來按照比例縮小規模,簡化分割解決方案的創建和管理。
作者簡介:Hilary Cotter進入IT這一行已經超過20年了,現在是網絡和數據庫顧問。微軟在2001年最先嘉獎Cotter為微軟SQL Server MVP。Cotter在多倫多大學機械工程專業獲得了應用科學學士學位,接著在卡爾加里大學學習經濟,在伯克利學院學習計算機科學。他撰寫了一本有關SQL Server事務復制的書,現在致力于一本有關合并復制和微軟的查詢技術的書。
(t114)