本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
本節介紹建置區塊層,為您提供了可在應用程式中使用的設計模式。

複合排序索引鍵建置區塊
當人們認為否時SQL,他們也可能將其視為非關聯性。最終,DynamoDB 結構描述中無法放入關係是不合理的,它們只是看起來與關聯式資料庫及其外部索引鍵不同而已。其中一項可以用來在 DynamoDB 中開發資料邏輯階層的最關鍵模式,就是複合排序索引鍵。最常見的設計模式,是以井字號將階層中的每一層 (父層 > 子層 > 孫層) 隔開。例如:PARENT#CHILD#GRANDCHILD#ETC
。

雖然 DynamoDB 中的分割區索引鍵一律需要確切的值才能查詢資料,但我們可以將部分條件從左至右套用至排序索引鍵,類似於遍歷二元樹。
在上面的範例中,我們有一間需要在使用者工作階段中維護購物車的電子商務商店。每當使用者登入時,他們可能希望看到整個購物車,包括儲存供日後使用的項目。但是,在他們進入結帳程序時,只應載入使用中購物車內的項目以供購買。由於這兩個都KeyConditions
明確要求CART排序索引鍵,因此 DynamoDB 在讀取時只會忽略其他的願望清單資料。雖然儲存的項目和使用中的項目都屬於同一個購物車,但我們需要在應用程式的不同部分中以不同的方式處理它們,因此在排序索引鍵的字首上套用 KeyCondition
,是僅擷取應用程式每個部分所需資料的最佳方式。
此建置區塊的主要特徵
-
相關項目彼此在本機儲存,以便有效存取資料
-
使用
KeyCondition
表達式,可以選擇性地擷取階層的子集,表示沒有浪費 RCUs -
應用程式的不同部分可以將其項目儲存在特定字首下,防止被覆寫的項目或衝突的寫入
多租戶建置區塊
許多客戶使用 DynamoDB 來託管多租戶應用程式的資料。針對這些案例,我們想要設計結構描述,以便將單一租戶的所有資料保留在其本身的資料表邏輯分割區中。這會利用「項目集合」的概念,該術語是指 DynamoDB 資料表中具有相同分割區索引鍵的所有項目。如需 DynamoDB 如何處理多租戶的詳細資訊,請參閱 Multitenancy on DynamoDB。

在此範例中,我們正在執行一個可能有成千上萬使用者的相片託管網站。每個使用者最初只會將相片上傳到自己的個人資料,但預設情況下,我們不允許使用者查看任何其他使用者的相片。理想上,每個使用者對 呼叫的授權會新增額外的隔離層級API,以確保他們只從自己的分割區請求資料,但在結構描述層級,唯一的分割區索引鍵是足夠的。
此建置區塊的主要特徵
-
任何一位使用者或租用戶讀取的資料量只能與其分割區中的項目總量相同
-
由於帳戶關閉或合規要求而需刪除租戶資料,可以巧妙而廉價的方式完成。只要執行分割區索引鍵等於其租戶 ID 的查詢,然後為傳回的每個主索引鍵執行
DeleteItem
操作
注意
以多租用戶為設計考量,您可以在單一資料表中使用不同的加密金鑰提供者來安全地隔離資料。Amazon DynamoDB 的AWS 資料庫加密SDK可讓您在 DynamoDB 工作負載中包含用戶端加密。您可以執行屬性層級加密,讓您在將特定屬性值儲存在 DynamoDB 資料表之前先加密,並搜尋加密的屬性,而無需事先解密整個資料庫。
稀鬆索引建置區塊
有時,存取模式需要尋找符合罕見項目的項目,或是接收狀態的項目 (需要提升回應)。我們可以利用全域次要索引 (GSI) 隨資料少量載入的事實,而不是在整個資料集中定期查詢這些項目。這表示只有基底資料表中具有在索引中定義之屬性項目,才會複寫至索引。


在此範例中,我們看到IOT使用案例,其中 欄位中的每個裝置都會定期回報狀態。對於大多數報告,我們期望裝置會報告一切正常,但有時可能會出現故障,必須提升給維修技術人員處理。對於具有升級的報告而言,系統會新增該項目的屬性 EscalatedTo
,但不會顯示該屬性。此範例中GSI的 會依 進行分割,EscalatedTo
因為 會從基礎資料表GSI接管索引鍵,我們仍然可以看到哪些 DeviceID 報告故障,以及何時報告故障。
雖然在 DynamoDB 中的讀取成本比寫入低,但稀疏索引是非常強大的工具,適用於特定類型項目的執行個體罕見,但讀取以找到它們卻很常見的使用案例。
此建置區塊的主要特徵
-
稀疏的寫入和儲存成本GSI僅適用於符合金鑰模式的項目,因此 的成本GSI可以遠低於GSIs將所有項目複寫到它們的其他成本
-
複合排序索引鍵仍可用來進一步縮小符合所需查詢的項目範圍,例如,排序索引鍵可以使用時間戳記,以便只檢視最後 X 分鐘內報告的錯誤 (
SK > 5 minutes ago, ScanIndexForward: False
)
建置區塊生存時間
大多數資料都有一定的持續時間,可以視為值得保存在主要資料儲存中。為了促進資料從 DynamoDB 過時,它有一個稱為存留時間 (TTL) 的功能。TTL 此功能可讓您在資料表層級定義特定屬性,該屬性需要監控具有 epoch 時間戳記 (過去) 的項目。這使您可以免費從資料表中刪除過期記錄。
注意
如果您使用的是全域資料表 2019.11.21 版 (目前) 的全域資料表,而且也使用存留時間功能,則 DynamoDB 會複寫TTL刪除所有複本資料表。初始TTL刪除不會在發生TTL過期的區域使用寫入容量。不過,複寫TTL刪除至複本資料表 (複本) 會在每個複本區域中耗用複寫寫入容量,並收取適用的費用。

在此範例中,我們有一個應用程式專門設計用來讓使用者建立短期訊息。在 DynamoDB 中建立訊息時,應用程式程式碼會將 TTL 屬性設定為未來七天的日期。在大約七天內,DynamoDB 會看到這些項目的 epoch 時間戳記已經過去,並將其刪除。
由於 刪除TTL是免費的,強烈建議使用此功能從資料表中移除歷史資料。這將減少每個月的整體儲存體費用,並可能降低使用者讀取成本,因為他們查詢擷取的資料將較少。當 在資料表層級啟用 TTL 時,由您決定要為哪些項目或實體建立TTL屬性,以及未來要將 epoch 時間戳記設定為多遠。
此建置區塊的主要特徵
-
TTL 刪除會在幕後執行,不會影響您的資料表效能
-
TTL 是一種非同步程序,大約每 6 小時執行一次,但可能需要超過 48 小時才能刪除過期的記錄
-
如果必須在不到 48 小時內清除過時的資料,則不要依賴TTL刪除鎖定記錄或狀態管理等使用案例
-
-
您可以為 TTL 屬性命名有效的屬性名稱,但值必須是數字類型
封存建置區塊生存時間
雖然 TTL 是從 DynamoDB 刪除較舊資料的有效工具,但許多使用案例需要將資料封存保留比主要資料存放區更長的時間。在此執行個體中,我們可以利用 TTL的記錄的定時刪除,將過期的記錄推送到長期資料存放區。

TTL 刪除由 DynamoDB 完成時,仍會以Delete
事件的形式推送至 DynamoDB Stream。當 DynamoDB TTL 執行刪除時,在 的串流記錄上會有 屬性principal:dynamodb
。使用 DynamoDB 串流的 Lambda 訂閱用戶,我們可以僅對 DynamoDB 主體屬性套用事件篩選條件,並知道與該篩選條件相符的任何記錄,都將被推送到 S3 Glacier 等封存儲存。
此建置區塊的主要特徵
-
一旦歷史項目不再需要 DynamoDB 的低延遲讀取,將它們遷移到像 S3 Glacier 這樣的較冷的儲存體服務可大幅降低儲存成本,同時滿足使用案例的資料合規需求
-
如果資料保留在 Amazon S3 中,則可以使用具成本效益的分析工具 (如 Amazon Athena 或 Redshift Spectrum) 來執行資料的歷史分析
垂直分割建置區塊
熟悉文件模型資料庫的使用者將熟悉將所有相關資料儲存在單一JSON文件中的概念。雖然 DynamoDB 支援JSON資料類型,但不支援在巢狀 KeyConditions
上執行JSON。由於 KeyConditions
是規定要從磁碟讀取多少資料,以及RCUs查詢有效耗用多少資料的原因,這可能會導致大規模的效率低下。為了更最佳化 DynamoDB 的寫入和讀取,我們建議您將文件的個別實體分割為個別 DynamoDB 項目,也稱為垂直分割。


如上所示,垂直分割是實際操作中單一資料表設計的關鍵範例,但如果需要,也可以跨多個資料表進行實作。由於 DynamoDB 帳單會以 1 KB 的增量進行寫入,因此理想情況下,您應該以產生小於 1 KB 項目的方式對文件進行分割。
此建置區塊的主要特徵
-
資料關係的階層是透過排序索引鍵字首維護的,因此如果需要,可以在用戶端重建單一文件結構
-
資料結構的單一元件可以獨立更新,導致小型項目更新只有 1 WCU
-
透過使用排序索引鍵
BeginsWith
,應用程式可在單一查詢中擷取類似資料,彙總讀取成本以降低總成本/延遲 -
大型文件可輕易地超過 DynamoDB 中的 400 KB 個別項目大小限制,而垂直分割則有助於解決此限制
寫入碎片建置區塊
DynamoDB 的極少數硬性限制之一,就是單一實體分割區每秒可維持多少輸送量 (不一定是單一分割區索引鍵) 的限制。這些限制目前是:
-
1000 WCU(或 1000 <=1KB 項目每秒寫入) 和 3000 RCU(或 3000 <=4KB 每秒讀取) 高度一致或
-
每秒 6000 <= 4 KB 讀取最終一致
如果資料表的請求超過這些限制,則會將錯誤傳回 SDK用戶端ThroughputExceededException
,這通常稱為限流。需要超過該限制的讀取操作使用案例,通常是將讀取快取放在 DynamoDB 前面,以達到最佳效果,但是寫入操作需要稱為寫入碎片的結構描述層級設計。


為了解決此問題,我們將在應用程式的 UpdateItem
代碼中的每個競爭者的分割區索引鍵結尾附加一個隨機整數。隨機整數產生器的範圍,將需要具有上限相符或超過指定競爭者每秒的寫入量除以 1000。為了支援每秒 20,000 次投票,它看起來會像 rand (0,19)。現在該資料儲存在單獨的邏輯分割區下,它必須在讀取時重新合併在一起。由於投票總數不需要是即時的,因此排定為每 X 分鐘讀取所有投票分割區的 Lambda 函數可能會偶爾為每位競爭者執行彙總,並將其寫回單一投票總記錄以供即時讀取。
此建置區塊的主要特徵
-
對於無法避免的指定分割區索引鍵具有極高寫入輸送量的使用案例,可以人為將寫入操作分散到多個 DynamoDB 分割區
-
GSIs 具有低基數分割區索引鍵時,也應該利用此模式,因為 上的調節GSI會施加背壓來寫入基礎資料表上的操作