# 云計算設計模式(十二)——索引表模式
創建索引過的被查詢條件經常被引用的數據存儲等領域。這種模式可以通過允許應用程序更快速地定位數據來從數據存儲中檢索提高查詢性能。
## 背景和問題
許多數據存儲通過使用主鍵組織為實體的集合的數據。應用程序可以使用此鍵來查找和檢索數據。圖 1 顯示了一個數據存儲區保持顧客的信息的例子。主鍵是客戶 ID。

圖1 - 按主鍵組織的客戶信息(客戶ID)
而主鍵是該取基于該關鍵字的值的數據的查詢寶貴的,應用程序可能不能夠使用主鍵是否需要基于其它字段來檢索數據。在顧客例如,應用程序不能使用該客戶ID主鍵來檢索客戶,如果它通過指定引用的一些其他屬性的值,如在其中客戶位于鎮標準查詢數據完全。要執行一個查詢,如這可能需要申請獲取并檢查每一個客戶的記錄,這可能是一個緩慢的過程。
許多關系數據庫管理系統支持二級索引。一種二次指數是由一個或多個非主(輔助)鍵領域舉辦一個單獨的數據結構,它表示,其中每個索引值的數據被存儲。在一第二索引的項目通常排序方法的第二個鍵的值,使數據的快速查找。這些指標通常是由數據庫管理系統自動進行維護。
由于需要支持您的應用程序執行不同的查詢,您可以創建任意多個二級指標。例如,在一個關系數據庫中凡客ID是主鍵的表的客戶,也可能是有益的補充輔助指數在鎮域如果應用程序頻繁查找的客戶在其居住的小鎮。
然而,盡管二級指標是關系型系統的共同特征,使用云應用大部分NoSQL數據存儲不提供同等的功能。
## 解決方案
如果數據存儲不支持??二級索引,你可以通過創建自己的索引表手動效仿他們。索引表由指定的鍵組織數據。三種策略通常用于構建一個索引表,這取決于所需要的二次索引的數目和該應用程序執行的查詢的性質:
重復數據的每個索引表中,而是由不同的密鑰(完全非規范化)組織它。圖2顯示了索引表的組織包括城市和姓氏相同的客戶信息:

圖2 - 索引表執行二級指標的客戶數據。數據被復制到每個索引表中。
如果比較的時候,它是通過使用每個鍵查詢的數目的數據是相對靜態的這一策略可能是適當的。如果數據是更加動態,保持每個索引表的處理開銷可能會變得太大,這種方法是有用的。此外,如果數據量非常大,空間來存儲重復的數據所需要的量將顯著。
創建由不同的密鑰組織的歸索引表和通過使用主鍵而不是重復它引用原始數據,如示于圖3中的原始數據被稱為一個事實表:

圖3 - 索引表執行二級指標的客戶數據。該數據是由每個索引表所引用。
這種技術可以節省空間,降低了維護的重復數據的開銷。的缺點是,一個應用程序具有通過使用第二密鑰來執行兩個查找操作以查找數據(找到的主鍵的索引表中的數據,然后查找在事實表中的數據通過使用主鍵)。
創建由重復的頻繁檢索的字段不同的按鍵組織的部分歸索引表。引用原始數據來訪問較少頻繁訪問的字段。圖4示出了這種結構。

圖4 - 索引表執行二級指標的客戶數據。經常訪問的數據是重復的每個索引表中。
使用這種技術,你可以前兩種方法之間取得平衡。可以快速地檢索到通過使用單個查找,常用的查詢數據,而空間和維護開銷是不一樣大,復制整個數據集。
如果應用程序通過指定值的組合頻繁地查詢數據(例如,“查找生活在雷德蒙和具有史密斯的姓所有客戶”),則可以實現鍵的索引表中的項目作為一個級聯城市屬性和姓氏屬性的,如示于圖5中的鍵由鎮排序,然后通過名字為那些具有鎮相同的值的記錄。

圖5 - 基于復合主鍵索引表
索引表可以加快了分片的數據查詢操作,并在那里的碎片密鑰散列特別有用。圖 6 顯示了一個示例,其中分片密鑰是客戶 ID 的散列。索引表可以由非散列值(城市和名字)組織數據,并提供該哈希分片鍵作為查找數據。這樣可以節省從重復計算散列鍵的應用(其可以是昂貴的操作),如果它需要檢索的數據落在一個范圍之內,或者它需要讀取的數據,以便在非散列密鑰。例如,諸如“查找生活在雷德蒙所有客戶”可以由通過定位在索引表中的匹配項(其全部存儲在一個連續的塊),并按照引用的客戶數據盡快解決的查詢使用存儲在索引表中的碎片的鍵。

圖6 - 索引表中提供了快速查找的分片數據
## 問題和注意事項
在決定如何實現這個模式時,請考慮以下幾點:
- 保持輔助索引的開銷可能是顯著。你必須分析和了解,您的應用程序使用的查詢。只創建他們很可能被經常使用的索引表。不要投機創建索引的表,以支持應用程序不執行查詢,或者一個應用程序只執行非常偶然。
- 在索引表中復制的數據所用的存儲成本和維護數據的多個副本所需的工作條件添加顯著開銷。
- 執行一個索引表,作為標準化的結構,引用原始數據可能需要的應用程序,以執行兩個查找操作以查找數據。第一操作搜索索引表來檢索主鍵,第二個使用的主密鑰來獲取數據。
- 如果系統包含大量索引表在非常大的數據集,也可以是難以維持索引表和原始數據之間的一致性。有可能設計圍繞最終一致性模型的應用。例如,插入,更新或刪除數據,一個應用程序可以發送一條消息給一個隊列,并讓一個獨立的任務執行操作和維護引用該數據不同步的索引表。有關實現最終一致性的更多信息,請參閱數據一致性底漆。
> 注意: 微軟 Azure 存儲表支持事務更新到同一個分區中保存的數據進行更改(簡稱實體組的事務)。如果你可以存儲一個事實表和在同一個分區的一個或多個索引表中的數據,您可以使用此功能來幫助確保一致性。
索引表可以自行進行分區或分片。
## 何時使用這個模式
使用這種模式來提高查詢性能,當應用程序經常需要使用一鍵以外的主(或子庫)鍵來檢索數據。
這種模式可能不適合時:
- 數據是不穩定的。索引表可能變得過時的速度非常快,使其無效,或者使保持在索引表大于用它制成的任何節省的開銷。
- 選作索引表中的二級密鑰的場是非常不鑒別,只能有一個小的值的集合(例如,性別)。
- 數據值的選擇為一個索引表中的二級密鑰的場的平衡是高度傾斜。例如,如果 90% 的記錄中包含相同的值中的一個字段,然后創建和維護一個索引表中查找基于該字段中的數據可以施加更大的開銷比通過數據掃描順序。然而,如果查詢非常頻繁地針對位于對剩余的 10% 的值,該索引可以是有用的。你必須明白的疑問,您的應用程序正在執行,以及如何他們經常執行。
## 例子
Azure 存儲表在云中運行的應用程序提供了一個高度可擴展的鍵/值數據存儲。應用程序存儲,并通過指定一個鍵檢索數據值。的數據值可以包含多個字段,但一個數據項的結構是不透明的表存儲,這僅僅處理一個數據項作為一個字節數組。
Azure 存儲表還支持分片。分片密鑰包括兩個元件,一個分區鍵和行密鑰。有相同的分區鍵的數據項都存儲在同一分區(碎片),并且項目被存儲在一個子庫中排鍵順序。表存儲優化用于執行獲取數據下降分區中的連續范圍的行鍵值范圍內的查詢。如果您正在構建存儲在 Azure 的表的信息的云應用,你應該組織你的數據在考慮這個功能。
例如,考慮存儲有關電影的信息的應用程序。應用程序經常按流派查詢電影(動作片,紀錄片,歷史,喜劇,戲劇,等等)。可以通過使用類型作為分區鍵,并指定電影的名稱作為行密鑰創建一個天青表的分區的每個類型,如圖7。

圖7 - 存儲在 Azure Table 中的電影數據,按流派劃分和排序的電影名稱
這種方法不太有效,如果該應用程序還需要通過演員主演查詢電影。在這種情況下,你可以創建一個單獨的Azure表作為一個索引表。分區鍵是演員和行關鍵是電影的名字。對于每個演員的數據將被存儲在單獨的分區。如果一個電影明星不止一個演員,同一部電影會出現在多個分區。
可以通過采用上面的解決方案部分中所述的第一種方式重復在每個分區中保存的值的電影數據。然而,很可能是每個影片將(對于每個演員一次)重復幾次,所以它可能是更有效的,以部分非規范化,以支持最常見的查詢(如其他演員的姓名)的數據,并實現一個應用程序由包括必要找到在體裁分區的完整信息,分區鍵來檢索任何剩余的細節。這種方法是通過在解決方案部分中的第三項中的說明。圖8描述了這種方法。

圖8 - 演員分區作為索引表的影像數據
- 前言
- (一)—— 緩存預留模式
- (二)—— 斷路器模式
- (三)—— 補償交易模式
- (四)——消費者的競爭模式
- (五)——計算資源整合模式
- (六)——命令和查詢職責分離(CQRS)模式
- (七)——事件獲取模式
- (八)——外部配置存儲模式
- (九)—— 聯合身份模式
- (十)——守門員模式
- (十一)—— 健康端點監控模式
- (十二)—— 索引表模式
- (十三)——領導人選舉模式
- (十四)——實體化視圖模式
- (十五)—— 管道和過濾器模式
- (十六)——優先級隊列模式
- (十七)—— 基于隊列的負載均衡模式
- (十八)—— 重試模式
- (十九)——運行重構模式
- (二十)—— 調度程序代理管理者模式
- (二十一)——Sharding 分片模式
- (二十二)——靜態內容托管模式
- (二十三)——Throttling 節流模式
- (二十四)—— 仆人鍵模式