1. 程式人生 > >資料庫儲存大資料量(千萬條記錄級別)資料的考慮要點

資料庫儲存大資料量(千萬條記錄級別)資料的考慮要點

分割槽
 將資料庫分割槽可提高其效能並易於維護。通過將一個大表拆分成更小的單個表,只訪問一小部分資料的查詢可以執行得更快,因為需要掃描的資料較少。而且可以更快地執行維護任務(如重建索引或備份表)。
 實現分割槽操作時可以不拆分表,而將表物理地放置在個別的磁碟驅動器上。例如,將表放在某個物理驅動器上並將相關的表放在與之分離的驅動器上可提高查詢效能,因為當執行涉及表之間聯接的查詢時,多個磁頭同時讀取資料。可以使用 Microsoft® SQL Server™ 2000 檔案組指定將表放置在哪些磁碟上。
 
 硬體分割槽
 硬體分割槽將資料庫設計為利用可用的硬體構架。硬體分割槽的示例包括:
 允許多執行緒執行的多處理器,使得可以同時執行許多查詢。換句話說,在多處理器上可以同時執行查詢的各個元件,因此使單個查詢的速度更快。例如,查詢內引用的每個表可同時由不同的執行緒掃描。


 RAID(獨立磁碟冗餘陣列)裝置允許資料在多個磁碟驅動器中條帶化,使更多的讀/寫磁頭同時讀取資料,因此可以更快地訪問資料。在多個驅動器中條帶化的表一般比儲存在一個驅動器上的相同的表掃描速度要快。換句話說,將表與相關的表分開儲存在不同的驅動器上可以顯著提高聯接那些表的查詢的效能。


 水平分割槽
 水平分割槽將一個表分段為多個表,每個表包含相同數目的列和較少的行。例如,可以將一個包含十億行的表水平分割槽成 12 個表,每個小表代表特定年份內一個月的資料。任何需要特定月份資料的查詢只引用相應月份的表。
 具體如何將表進行水平分割槽取決於如何分析資料。將表進行分割槽是為了使查詢引用盡可能少的表。否則,查詢時須使用過多的 UNION 查詢來邏輯合併表,而這會削弱查詢效能。有關查詢水平分割槽的表的更多資訊,請參見檢視使用方案。
 常用的方法是根據時期/使用對資料進行水平分割槽。例如,一個表可能包含最近五年的資料,但是隻定期訪問本年度的資料。在這種情況下,可考慮將資料分割槽成五個表,每個表只包含一年的資料。
 
 垂直分割槽
 垂直分割槽將一個表分段為多個表,每個表包含較少的列。垂直分割槽的兩種型別是規範化和行拆分。
 規範化是個標準資料庫程序,該程序從表中刪除冗餘列並將其放到次表中,次表按主鍵與外來鍵的關係連結到主表。
 行拆分將原始表垂直分成多個只包含較少列的表。拆分的表內的每個邏輯行與其它表內的相同邏輯行匹配。例如,聯接每個拆分的表內的第十行將重新建立原始行。
 與水平分割槽一樣,垂直分割槽使查詢得以掃描較少的資料,因此提高查詢效能。例如有一個包含七列的表,通常只引用該表的前四列,那麼將該表的後三列拆分到一個單獨的表中可獲得性能收益。
 應謹慎考慮垂直分割槽操作,因為分析多個分割槽內的資料需要有聯接表的查詢,而如果分割槽非常大將可能影響效能。


 請參見
 使用分割槽檢視
 
 
使用分割槽檢視
 分割槽檢視允許將大型表中的資料拆分成較小的成員表。根據其中一列中的資料值範圍,將資料在各個成員表之間進行分割槽。每個成員表的資料範圍都在為分割槽列指定的 CHECK 約束中定義。然後定義一個檢視,以使用 UNION ALL 將選定的成員表組合成單個結果集。引用該檢視的 SELECT 語句為分割槽列指定搜尋條件後,查詢優化器將使用 CHECK 約束定義確定哪個成員表包含這些行。
 例如,記錄 1998 年銷售額的 sales 表分割槽成 12 個成員表,每個月是一個成員表。每個成員表在 OrderMonth 列上都定義了約束:
 CREATE TABLE May1998Sales
    (OrderID   INT      PRIMARY KEY,
    CustomerID      INT         NOT NULL,
    OrderDate      DATETIME      NULL
       CHECK (DATEPART(yy, OrderDate) = 1998),
    OrderMonth      INT
       CHECK (OrderMonth = 5),
    DeliveryDate      DATETIME      NULL,
       CHECK (DATEPART(mm, OrderDate) = OrderMonth)
    )
 填充 May1998Sales 的應用程式必須確保所有行在 OrderMonth 列中均為 5,並且訂購日期指定 1998 年 5 月的某個日期。該表上定義的約束強制實現這一要求。
 然後定義一個檢視,以使用 UNION ALL 選定全部 12 個成員表中的資料作為單個結果集:
 CREATE VIEW Year1998Sales
 AS
 SELECT * FROM Jan1998Sales
 UNION ALL
 SELECT * FROM Feb1998Sales
 UNION ALL
 SELECT * FROM Mar1998Sales
 UNION ALL
 SELECT * FROM Apr1998Sales
 UNION ALL
 SELECT * FROM May1998Sales
 UNION ALL
 SELECT * FROM Jun1998Sales
 UNION ALL
 SELECT * FROM Jul1998Sales
 UNION ALL
 SELECT * FROM Aug1998Sales
 UNION ALL
 SELECT * FROM Sep1998Sales
 UNION ALL
 SELECT * FROM Oct1998Sales
 UNION ALL
 SELECT * FROM Nov1998Sales
 UNION ALL
 SELECT * FROM Dec1998Sales
 例如,下面的 SELECT 語句查詢特定月的資訊。
 SELECT *
 FROM Year1998Sales
 WHERE OrderMonth IN (5,6) AND CustomerID = 64892
 SQL Server 查詢優化器識別出此 SELECT 語句中的搜尋條件只引用 May1998Sales 和 Jun1998Sales 表中的行,從而將其搜尋範圍限制在這些表上。
 分割槽檢視返回正確的結果並不一定非要 CHECK 約束。但是,如果未定義 CHECK 約束,則查詢優化器必須搜尋所有表,而不是隻搜尋符合分割槽列上的搜尋條件的表。如果不使用 CHECK 約束,則檢視的操作方式與帶有 UNION ALL 的任何其它檢視相同。查詢優化器不能對儲存在不同表中的值作出任何假設,也不能跳過對參與檢視定義的表的搜尋。
 如果分割槽檢視所引用的所有成員表都在同一伺服器上,則該檢視是本地分割槽檢視。如果成員表在多臺伺服器上,則該檢視是分散式分割槽檢視。分散式分割槽檢視可用於在一組伺服器間分佈系統的資料庫處理工作量。
 分割槽檢視使獨立地維護成員表變得更容易。例如,在某個階段結束時:
 可以更改當前結果的分割槽檢視定義以新增最新的階段和除去最早的階段。


 可以更改以前結果的分割槽檢視定義以新增剛從當前結果檢視中除去的階段。也可以更新以前的結果檢視以刪除或存檔該檢視所包含的最早階段。
 將資料插入到分割槽檢視中後,就可以使用 sp_executesql 系統儲存過程建立 INSERT 語句,該語句帶有在有許多併發使用者的系統中重新使用機率較高的執行計劃。
 
建立分割槽檢視
 分割槽檢視在一個或多個伺服器間水平連線一組成員表中的分割槽資料,使資料看起來就象來自一個表。Microsoft® SQL Server™ 2000 區分本地分割槽檢視和分散式分割槽檢視。在本地分割槽檢視中,所有的參與表和檢視駐留在同一個 SQL Server 例項上。在分散式分割槽檢視中,至少有一個參與表駐留在不同的(遠端)伺服器上。此外,SQL Server 2000 還區分可更新的分割槽檢視和作為基礎表只讀複本的檢視。
 分散式分割槽檢視可用於實現資料庫伺服器聯合體。聯合體是一組分開管理的伺服器,但它們相互協作分擔系統的處理負荷。這種通過分割槽資料形成資料庫伺服器聯合體的機制使您能夠擴大一組伺服器,以支援大型的多層 Web 站點的處理需要。有關更多資訊,請參見設計聯合資料庫伺服器。
 在實現分割槽檢視之前,必須先水平分割槽表。原始表被分成若干個較小的成員表。每個成員表包含與原始表相同數量的列,並且每一列具有與原始表中的相應列同樣的特性(如資料型別、大小、排序規則)。如果正在建立分散式分割槽檢視,則每個成員表分別位於不同的成員伺服器上。為了獲得最大程度的位置透明度,各個成員伺服器上的成員資料庫的名稱應當是相同的,但不要求非這樣。例如:Server1.CustomerDB、Server2.CustomerDB、Server3.CustomerDB。
 成員表設計好後,每個表基於鍵值的範圍儲存原始表的一塊水平區域。鍵值範圍基於分割槽列中的資料值。每一成員表中的值範圍通過分割槽列上的 CHECK 約束強制,並且範圍之間不能重疊。例如,不能使一個表的值範圍從 1 到 200000,而另一個表的值範圍從 150000 到 300000,因為這樣將不清楚哪個表包含 150000 與 200000 之間的值。
 例如,正在將一個 Customer 表分割槽成三個表。這些表的 CHECK 約束為:
 -- On Server1:
 CREATE TABLE Customer_33
   (CustomerID   INTEGER PRIMARY KEY
                 CHECK (CustomerID BETWEEN 1 AND 32999),
   ... -- Additional column definitions)
 -- On Server2:
 CREATE TABLE Customer_66
   (CustomerID   INTEGER PRIMARY KEY
                 CHECK (CustomerID BETWEEN 33000 AND 65999),
   ... -- Additional column definitions)
 -- On Server3:
 CREATE TABLE Customer_99
   (CustomerID   INTEGER PRIMARY KEY
                 CHECK (CustomerID BETWEEN 66000 AND 99999),
   ... -- Additional column definitions)
 在建立成員表後,在每個成員伺服器上定義一個分散式分割槽檢視,並且每個檢視具有相同的名稱。這樣,引用分散式分割槽檢視名的查詢可以在任何一個成員伺服器上執行。系統操作如同每個成員伺服器上都有一個原始表的複本一樣,但其實每個伺服器上只有一個成員表和一個分散式分割槽檢視。資料的位置對應用程式是透明的。
 生成分散式分割槽檢視的方式如下:
 在每一個含有在其它成員伺服器上執行分散式查詢所需連線資訊的成員伺服器上新增連結伺服器定義。這將使得分散式分割槽檢視能夠訪問其它伺服器上的資料。


 對於在分散式分割槽檢視中使用的每個連結伺服器定義,使用 sp_serveroption 設定 lazy schema validation 選項。這確保了只有在實際需要遠端成員表的資料時,查詢處理器才請求任何連結表的元資料,從而使效能得到優化。


 在每個成員伺服器上建立分散式分割槽檢視。這些檢視使用分散式 SELECT 語句訪問連結成員伺服器上的資料,並將分散式行與本地成員表的行合併。
 若要為上一個示例建立分散式分割槽檢視,應當:
 為 Server2 新增一個名為 Server2 的、帶有連線資訊的連結伺服器定義,並新增一個名為 Server3 的連結伺服器定義以訪問 Server3。


 建立以下分散式分割槽檢視:
 CREATE VIEW Customers AS
    SELECT * FROM CompanyDatabase.TableOwner.Customers_33
 UNION ALL
    SELECT * FROM Server2.CompanyDatabase.TableOwner.Customers_66
 UNION ALL
    SELECT * FROM Server3.CompanyDatabase.TableOwner.Customers_99
 在 Server2 和 Server3 上執行相同的步驟。
 可更新的分割槽檢視
 如果本地或分散式分割槽檢視為不可更新的,則它只能作為原始表的只讀複本。可更新的分割槽檢視可展示出原始表的所有功能。
 在下列情況中,檢視被視為可更新的分割槽檢視:
 檢視是一組 SELECT 語句,這些語句的結果集通過 UNION ALL 語句組合為一個結果集。每個 SELECT 語句引用一個 SQL Server 基表。該表可以是本地表,也可以是使用 4 部分名稱、OPENROWSET 函式或 OPENDATASOURCE 函式引用的連結表(不能使用 OPENDATASOURCE 或 OPENROWSET 函式指定直接傳遞式查詢)。
 表規則
 成員表在檢視定義中的每個 SELECT 語句的 FROM 子句中定義。每個成員表都必須遵守如下規則:
 在檢視中每個成員表只能引用一次。


 成員表不能有任何計算列上建立的索引。


 成員表在數目相同的列上應具有所有 PRIMARY KEY 約束。


 成員表必須有相同的 ANSI 填充設定。有關 ANSI 填充設定的更多資訊,請參見 SET ANSI_PADDING。
 列規則
 列在檢視定義中的每個 SELECT 語句的選擇列表中定義。列必須遵守如下規則。
 每個成員表中的所有列必須包含在選擇列表中。


 在選擇列表中不能多次使用同一列。


 在選擇列表中對列的引用不能多於一次。


 列必須位於選擇列表中的相同序號位置處。


 每個 SELECT 語句的選擇列表中的列必須是同一型別(包括資料型別、精度、小數位數和排序規則)。例如,以下檢視定義失敗,這是因為兩個 SELECT 語句中首列的資料型別不同:
 CREATE VIEW NonUpdatable
 AS
 SELECT IntPrimaryKey, IntPartNmbr
 FROM FirstTable
   UNION ALL
 SELECT NumericPrimaryKey, IntPartNmbr
 FROM SecondTable
 分割槽列規則
 分割槽列存在於每個成員表上,並且通過 CHECK 約束標識特定表中的可用資料。分割槽列必須遵守如下規則:
 每個基表都擁有鍵值由 CHECK 約束所強制的分割槽列。每個表的 CHECK 約束的鍵範圍與其它任何表互不重疊。任何分割槽列的給定值必須只能對映到一個表。CHECK 約束只能使用以下運算子:BETWEEN、AND、OR、<、<=、>、>=、=。


 在檢視中,分割槽列必須位於每個 SELECT 語句的選擇列表中相同的序號位置處。例如,分割槽列要麼總是每個選擇列表中的首列,要麼總是每個選擇列表中的第二列,依次類推。


 分割槽列不允許為空。


 分割槽列必須是表的主鍵的一部分。


 分割槽列不能是計算列。


 在分割槽列上必須僅有一個約束。如果有多於一個的約束,SQL Server 會忽略所有的約束並在確定檢視是否為分割槽檢視時不考慮這些約束。
 滿足所有上述規則的分割槽列將支援 SQL Server 2000 查詢優化器支援的所有優化。有關更多資訊,請參見解析分散式分割槽檢視。
 資料修改規則
 除了為可更新的分割槽檢視定義的規則外,引用該檢視的資料修改語句還必須遵守為 INSERT、UPDATE 和 DELETE 語句定義的規則。
 
 說明  只有在安裝了 Microsoft SQL Server 2000 企業版或 Microsoft SQL Server 2000 開發版時,才可通過分割槽檢視修改資料。


 INSERT 語句
 INSERT 語句通過分割槽檢視將資料新增到成員表中。INSERT 語句必須遵守下列規則:
 所有列必須包含在 INSERT 語句中,即使基表中的列可能為 NULL 或在基表中定義了 DEFAULT 約束。


 不能在 INSERT 語句的 VALUES 子句中指定 DEFAULT 關鍵字。


 INSERT 語句提供的值必須符合在一個成員表的分割槽列上定義的 CHECK 約束邏輯。


 如果一個成員表包含具有標識屬性的列,則不能使用 INSERT 語句。


 如果一個成員表包含 timestamp 列,則不能使用 INSERT 語句。


 如果存在具有同一檢視或任一成員表的自聯接,則不能使用 INSERT 語句。
 UPDATE 語句
 UPDATE 語句通過分割槽檢視在一個或多個成員表中修改資料。UPDATE 語句必須遵守下列規則:
 UPDATE 語句不能在 SET 子句中將 DEFAULT 關鍵字指定為值,即使列在相應的成員表中定義了 DEFAULT 值。


 不能更改具有標識屬性的列的值;不過可以更新其它列。


 如果列中包含 text、image 或 ntext 資料,則不能更改 PRIMARY KEY 的值。


 如果基表中包含 timestamp 列,則不能進行更新。


 如果存在具有同一檢視或成員表的自聯接,則不能進行更新。


 不能在 UPDATE 語句的 SET 子句中指定 DEFAULT 關鍵字。
 DELETE 語句
 DELETE 語句通過分割槽檢視在一個或多個成員表中刪除資料。DELETE 語句必須遵守如下規則:
 如果存在具有同一檢視或任一成員表的自聯接,則不能使用 DELETE 語句。
 分散式分割槽檢視規則
 除了為分割槽檢視定義的規則外,分散式(遠端)分割槽檢視還有下列附加條件:
 將啟動分散式事務以確保更新所影響的所有節點間的原子性。


 XACT_ABORT SET 選項必須設定為 ON。


 遠端表中的 smallmoney 和 smalldatetime 列分別對映為 money 和 datetime。因此,本地表中的相應列也應為 money 和 datetime。


 任何連結伺服器都不能是環回連結伺服器,即指向同一 SQL Server 例項的連結伺服器。
 如果檢視中含有 INSTEAD OF 觸發器,則不遵循上述規則而引用分割槽表的檢視可能仍然是可更新的。但是,查詢優化器不能總能夠為含有 INSTEAD OF 觸發器的檢視生成和遵循所有上述規則的分割槽檢視一樣有效的執行計劃。


幾乎可以按天分表,然後使用檢視連線起來,查詢分為三種,當天查詢,所有資料查詢,歷史資料查詢
這麼龐大的資料量建議使用oracle、db2這樣的資料庫

oracle裡面額可以做表分割槽,速度快很多

轉自:http://yaoyanzhu.iteye.com/blog/2005517