數據倉庫中事實表的水平分區
對于大型數據庫來說,其事實表的數據記錄數量往往會在很短的時間內迅猛地增長。有時候,難以對這樣的龐大的數據集進行有效的管理,甚至SQL查詢的性能和速度都會受到不利的影響。數據庫分區技術就應運而生了。對事實表進行水平分區,有利于改善大型數據庫的查詢和讀寫性能,并簡化數據庫管理。
表的水平分區是將表的行劃分為多個不重疊的單元。水平分區表中的每一個分區單元都是通過對某個屬性列的值進行邊界范圍界定的,例如日期、地理區劃、客戶名等等。(注:你可以考慮將每個分區單元存儲在不同的硬盤,以提高查詢性能)。雖然對于數據庫管理員和數據庫開發人員來說,對表進行水平分區并不是什么難事,不過在實際操作之前還是需要進行一定的規劃,因為你正在處理的可是超大量的數據。下面,我們會和大家探討一下什么時候應當對一個事實表進行水平分區,而進行水平分區的原因又是什么。此外,我們還會介紹如何使用SQL Server 2005的內置功能創建分區函數、分區方案和分區表。
為什么要對事實表進行水平分區?
大型表格(例如,具有億萬行的表)的管理難度很大,主要是因為表的規模太大,無論你對其進行任何操作都要花費大量的時間(例如,重新生成索引操作)。在一個事務數據庫中,關聯表(例如,涉及多對多關系的表)通常是擁有最多行數的表。在維度建模過程中,一個事實表相當于一個關聯表。就像事務數據庫中的關聯表一樣,事實表往往擁有比其相關維度更多的行。
分區可以將這些超大型的表分割成便于管理的小單元。如果你用于維護數據庫的時間在緊縮,而需要處理的數據量卻在不斷的增長,你就可以先對表進行分區,再按照分區來執行備份和恢復操作以及更新表統計信息等維護任務,而不是對整個表進行這些操作。SQL Server 2005將一個分區表的所有分區看作一個邏輯實體,而且在終端用戶面前,這些分區仍然以一個整體表的形式出現。
對表進行水平分區有以下原因:
◆可以更好地控制將每個分區放在存儲器的哪些位置,并利用多讀寫頭來實現快速查詢。
◆可以按分區來進行備份和恢復操作,索引的重新生成和重新組織也可以按照分區來執行,而且可以對索引本身進行分區。
◆可以直接通過一個包含分區列或索引列的WHERE語句進行查詢。
◆由于將鎖限制在分區,你可以減少鎖升級和鎖管理的開銷。
◆如果多個分區在同一個文件組,那么合并和分割分區就非常容易。
接下來的問題是什么表適合進行水平分區呢?適合進行水平分區的表包括包含數據量非常大的表、預計在近期內會數據量將會猛增的表、以及能夠根據某種業務屬性值(例如,財政年度)來直觀分割的表。這些表都必須包含一個能用來將行分割成獨立不重疊單元的非空屬性列,例如由銷售時間構成的列。
如果你的數據庫包含了一個大型表格,對這個表格進行查詢和更新操作時,執行的性能都沒能達到你的預期要求,那么你就可以考慮對表進行分區以提高查詢性能。SQL Server 2005能夠識別分區,也就是說,如果包含了涉及分區列或索引列(該索引也是分區索引)的WHERE語句的查詢運行很慢時,查詢策略只會訪問相關的分區,這樣查詢可以在小范圍記錄里進行。該功能可以顯著提高查詢性能。
#p#
創建分區函數
要對表進行分區,首先需要創建由一個指定的分區列和一系列范圍邊界值構成的分區函數。執行下面的例子中的指令為SALESFact表創建了分區函數:
CREATE PARTITION FUNCTION MyDateRangePF (datetime)
AS RANGE LEFT FOR VALUES (‘1/01/2003’, ‘1/01/2005’, ‘1/01/2007)
MyDateRangePF是分區函數的名稱。在本例的環境中,分區列通常是datetime數據類型的列,例如本例中為Date_of_Event列。將datetime記錄分離為不重疊的組很簡單。例如,如果業務規則和已知的業務查詢都表明按照銷售事件發生的日期來分割表是合理的話,那么你就可以將數據分割成兩年一組,就像上面的分區函數命令中所示。
(datetime)指定了分區列的數據類型,而RANGE LEFT規定了FOR VALUES所定義的邊界日期屬于每個邊界值間隔的哪一側。在范圍分區中,如果要分為四個分區,就定義三個邊界值,設置邊界值有兩種方法:RANGE LEFT或RANGE RIGHT。RANGE LEFT指定每個值為每個分區的上邊界,而RANGE RIGHT則指定每個值為下一個分區的下邊界。例如,上面的RANGE LEFT分區函數將數據分為四個分區,每個分區的取值范圍如下表所示。如果用RANGE RIGHT來替代上述命令的RANGE LEFT,而使用相同的邊界值,那么其分區取值范圍會發生變化,見下表。
從上面的表格可以看出,如果銷售事件發生的日期是2005年1月1日,那么對于RANGE LEFT分區函數,你會在第二個分區中找到這條記錄,而對于RANGE RIGHT分區函數,則要在第三個分區中找到該記錄。為了數據的一致性,也為了方便查詢,建議對所有創建的分區表都統一選擇其中一種方法設置邊界值。
每一個分區的取值范圍都在FOR VALUES語句明確規定了其邊界值。注意,如果你使用datetime數據類型作為邊界值,則必須為日期時間設定一個國際標準,特別是對在不同的時區都有分部的企業來說更是如此。SQL Server將美國英語作為該會話的默認語言,如果實際使用的是其他語言,必須創建用戶自定義函數將不同的日期格式轉換為美國英語格式,并在FOR VALUES子句中引用該自定義函數。
創建分區方案
現在分區函數已經創建完畢,接下來要創建一個分區方案。分區方案可以將以分區表或已分區索引的分區映射到不同的文件組,可以使用以下命令創建分區方案:
CREATE PARTITION SCHEME MyPartitionScheme
AS MyDateRangePF
TO (MyFilegroup1, MyFilegroup2, MyFilegroup3, MyFilegroup4, MyFilegroup5)
MyPartitionScheme是分區方案的名稱,而MyDateRangePF則是使用該分區方案的分區函數的名稱。該命令將分區函數所創建的分區映射到指定的一個或多個文件組。在上面的例子中,對分區按照Date_of_Event列使用分區函數MyDateRangePF的表的分區會按照下表所示分配到各個文件組:
上面的CREATE PARTITION FUNCTION命令包含了三個邊界值和四個分區。不管分區是按照RANGE RIGHT還是RANGE LEFT創建的,分區數都比邊界值數大1,每個表最多可以有1000個分區。那么為什么在本例中,分區數只有四個,卻設置了五個文件組而不是四個呢?在SQL Server中,當分區數少于文件組數的時候,會將***個沒有分配分區的文件組標記為NEXT USED,作為候選待用文件組,如本例中的MyFilegroup5。下面我們來看看在分區方案中,這個NEXT USED文件組是如何使用的而其重要性又有多大。
CREATE PARTITION FUNCTION命令中,***一個邊界值為1/01/2007,所以Date_of_Event列的值大于等于1/01/2007的行記錄都會被存儲到第四個分區(P4)中。當2009年1月1日來臨的時候,你可能會創建一個新的分區來維持你之前所建立的分區計劃。如果你使用不包含NEXT USED文件組的原始CREATE PARTITION SCHEME命令創建新分區,你將無法將現有的P4劃分成P4(保留2007年到2008年底數據的分區)和P5(存儲2009年1月1日及以后數據的分區)兩個分區。如果你的分區計劃需要定期創建的新分區來保存新數據(如本例),那么你就要保證在你的CREATE PARTITION SCHEME命令中包含了NEXT USED文件組。你不需要為這個文件組分配一個分區。相反,你可以將多個分區映射到一個文件組,設置可以將所有的分區都映射到一個文件組。不過,你無法將一個分區映射到多個不同的文件組。
創建分區方案可能是數據庫分區過程中最重要的一個步驟。在將來,你有可能需要將兩個相鄰分區的數據合并到一個分區里,也可能要為現有的分區增加一個邊界值,還可能需要將數據從一個密集的分區移動到一個空分區中。要執行這些操作,你都需要事先做好規劃,并創建分區方案來支持這些操作。
#p#
創建分區表
創建分區表和創建普通表的區別不大,你只需要在ON子句中引用分區方案的名稱就可以了,見以下命令:
CREATE TABLE SALESFact
(SalesFact_KEY bigint identity
(1, 1) primary not clustered NOT NULL,
Date_of_Event datetime NOT NULL)
ON MyPartitionScheme (Date_of_Event)
通過指定分區方案的名稱,你可以看出這個表是一個分區表。當然,在創建該表之前,分區方案和分區函數必須已經存在于數據庫當中。
你可以將多個分區的數據合并到一個分區里。不過,你每次只能合并兩個相鄰的分區,所以如果你想要將一個含有多個分區的表合并成不分區的表,你就需要重復很多次合并的步驟。運行以下命令可以將兩個表合并:
ALTER PARTITION FUNCTION
MyPartitionFunction()
MERGE RANGE (‘1/01/2003’)
上面的命令將會把***個分區(P1)合并到第二個分區(P2),也就是說,合并后P2分區將包含Date_of_Event值在1/01/05以前的所有行記錄。在數據庫內部(例如,在sys.partitions系統表中),將會記錄對分區所做的修改。原來的P1和P2將變成P1,原來的P3變為P2,原來的P4變為P3。建議在合并任何分區之前,先畫出數據庫圖表目錄,因為如果你在執行這些合并操作時不夠小心的話,有可能需要花費很多時間才能理清其中關系。
輕松管理超大型數據庫表
SQL Server 2005能夠將一個表水平分割成不重疊的單元,并將每個單元分配到一個獨立的分區中,使我們能夠輕松管理超大型的事實表。SQL Server 2005 的Enterprise版和Developer版都能夠識別分區,這樣寫操作就只需訪問相關分區的行,因此運行的速度比要訪問整個表的內容來得更快。
【編輯推薦】