簡體   English   中英

DynamoDB 表設計:我如何 model 建立一對多關系,我需要所有“一”項和按某些屬性排序的“多”項之一

[英]DynamoDB Table Design: How do I model a one to many relationship where I need all of the "one" items and one of "many" sorted by some attribute

我的整個職業生涯都在使用非規范化的關系數據庫。 為了實現一個單表設計,可以在類似“App Store”的個人項目上處理幾個特定的訪問模式,我很難忘記所有這些。

這是一個快速的 ERD。 有一個應用程序 model 由平台(iOS、Android)和捆綁標識符以及創建新版本時使用的默認值 map 標識。 每個 App 可以有 0 到多個版本,這些版本由版本號標識(這是一個連續的數值,並且在 App 的上下文中是唯一的)。 一個版本具有 IsReleased 屬性以及其他幾個屬性(如名稱、發行說明、二進制路徑等)。

訪問模式

  1. 列出每個應用程序的最新版本。
  2. 列出給定平台的每個應用程序的最新版本。
  3. 列出 IsReleased 為 1 的每個應用程序的最新版本。
  4. 列出 IsReleased 為 1 的給定平台的每個應用程序的最新版本。
  5. 獲取特定應用的最新版本。
  6. 獲取 IsReleased 為 1 的特定應用的最新版本。
  7. 獲取特定應用的所有版本。
  8. 獲取 IsReleased 為 1 的特定應用的所有版本。
  9. 獲取特定應用的默認屬性。

我遇到了 1 到 4 的問題,這張桌子是我要去的地方。 我很難使用 GSI,它會按排序順序為我提供單個版本的所有應用程序項目。

PK sk 默認值 應用名稱 版本 被釋放 其他屬性
app_ios_com.app.one defaults {... json... }
app_ios_com.app.one version_1 應用一 1 1
app_ios_com.app.one version_2 應用一 2 1
app_ios_com.app.one version_3 應用一 3 1
app_ios_com.app.two defaults {... json... }
app_ios_com.app.two version_1 應用二 1 1
app_ios_com.app.two version_2 應用二 2 0
app_ios_com.app.two version_3 應用二 3 0

例如,對於訪問模式 1,我想要:

PK sk 默認值 應用名稱 版本 被釋放 其他屬性
app_ios_com.app.one version_3 應用一 3 1
app_ios_com.app.two version_3 應用二 3 0

例如,對於訪問模式 3,我想要:

PK sk 默認值 應用名稱 版本 被釋放 其他屬性
app_ios_com.app.one version_2 應用一 3 1
app_ios_com.app.two version_1 應用二 1 1

我必須記住的一些數據限制:

  • 目前只有10到20個應用程序,但我需要能夠支持數百個
  • 大多數應用程序將有 100 到 200 個版本,其中有 20 到 30 個發布版本。 最大的應用程序有 1000 個版本,其中發布了 50 個。
  • 在后端,IsReleased 標志通常會從 0 切換到 1,但偶爾會從 0 切換到 1。
  • 平均版本項約為 2 KB。
  • IsReleased 為 1 的訪問模式變化更頻繁地使用。

我覺得解決方案就在我面前,但我不能指望它。

TLDR; 想到的解決方案是排行榜模式,用於在單獨的記錄中緩存最新的應用程序版本。 每當添加新版本時, DynamoDB Streams都會將更改作為事件發送到 lambda,然后再更新非規范化的最新記錄。

注意:您出色的文章中缺少一條信息:您需要多久執行一次latest查詢? 如果不是很頻繁,那么“掃描並完成”將適用於您當前的卷。 如果答案是每分鍾 1k 個latest查詢,那么情況就不同了。 好消息是您的基本表格設計是可靠的。 當出現性能/成本問題時,可以增量實施Latest的查詢優化,而不會弄亂表設計。

非規范化最新版本

我們將保留最新版本的非規范化副本,這是另一種聽起來很罪惡的DynamoDB 模式 當添加版本或更改發布狀態時,流觸發的 lambda 將使用更新 API 更新這些記錄。 如何存儲最新版本信息? 我們有幾種選擇:

  1. 將所有latest數據存儲在具有 map 屬性{app1: {latest version copy}, app2: ...}的 singleton 記錄中。 您可以將更多邏輯放入記錄中以處理isReleased項目,或者簡單地獲取記錄並在后端進行過濾。
  2. 使用每個應用程序一條記錄的全球二級索引。 每條記錄都有“最新”作為 app_id 的 GSI1PK 和app_id 記錄具有與#1 中相同的信息。
  3. 用作 GSI,每個應用程序有多個記錄。 像這樣的東西似乎有效。 例如,查詢 #4 將使用GSI1PK=Latest#Released AND begins_with(GSI1SI, "IOS")
GSI1PK              GSI1SK
Latest              app_ios_com.app.one
Latest              IOS#app_ios_com.app.one
Latest#Released     app_ios_com.app.one
Latest#Released     IOS#app_ios_com.app.one

注意:如果您有高查詢量和低基數, 熱分區可能是這些“排行榜”類型非正規化模式的問題。 如果這成為一個問題,您可以通過保留每個“最新”記錄的多個副本來解決它,例如,隨機查詢 X 個副本latest-copy1latest-copy2latest-copy3 Amazon 使用計算后綴調用此模式分片

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM