跳至內容
返回

快速理解 DynamoDB 的 Primary Key

快速理解 DynamoDB 的 Primary Key

在任何資料庫中,Primary Key(主鍵)都是一個獨一無二的識別符,用來標識資料表中的每一筆記錄。在關聯式資料庫(例如 MySQL 或 PostgreSQL)中,主鍵通常是一個單獨的欄位(像是 ID),但在 DynamoDB 這樣的 NoSQL 鍵值儲存系統中,主鍵的概念稍微不同,且更靈活。

DynamoDB 的主鍵有兩種類型:

單一主鍵,只使用 Partition Key(分區鍵)

複合主鍵,Partition Key 和 Sort Key(排序鍵)組成

這兩種類型決定了資料如何儲存、分割,以及如何被快速查詢。讓我們深入這兩者的運作方式。

兩種主鍵

單一主鍵

單一主鍵只使用 Partition Key,Partition Key 是 DynamoDB 的基礎主鍵類型。如果你的資料表只有 Partition Key,它就像是你資料的「門牌號碼」。

由於 DynamoDB 是分散式資料庫,資料會被分割到多個伺服器上以實現高可用性和擴展性。Partition Key 的值決定了資料的「家」在哪個分區,透過內部的雜湊函數(Hash Function),決定這筆資料會被儲存在哪個實體分區(Partition)。舉個例子:

假設你有一個 Users 資料表,Partition Key 是 UserID。當你儲存 UserID = “user123” 的資料時,DynamoDB 會把 “user123” 丟進雜湊函數,算出一個分區編號(例如 Partition 5),然後把資料丟去那裡。

複合主鍵

Partition Key + Sort Key。這種設計讓 DynamoDB 不只是一個簡單的鍵值儲存,還能支援範圍查詢(Range Query)。

Sort Key(排序鍵)是 Partition Key 的「副手」。在同一個 Partition Key 下,Sort Key 會決定資料的排序順序。想像 Partition Key 是「書架編號」,告訴你去哪個書架找,而 Sort Key 是「書的排序號」,讓你在書架上按順序找到書。

沒有這些「編號」,你就只能一本本翻閱整個圖書館。

Primary Key 在 DynamoDB 中的重要性

為什麼說理解 Primary Key 是理解 DynamoDB 的關鍵?因為它直接影響:

  1. 資料儲存:Partition Key 決定資料如何分散到多個分區,影響效能和擴展性。

  2. 查詢效率:DynamoDB 的查詢基本上都依賴主鍵(除非用索引,但那是另一個話題)。沒有主鍵,你無法快速找到資料。

  3. 成本:熱點問題或不當的主鍵設計會導致效能瓶頸,增加讀寫容量單位的消耗。

把 GSI (Global Secondary Index) 當成是另一種類型的 Primary Key

由於 Primary Key 就是你的搜尋或查詢方式,它是一種資料的呈現面向,但資料可能需要呈現的維度通常是多維的,例如研討會是以學員報到為核心,查詢時以找到學員這個人為目標。但如果研討會供餐,就需要從另一個維度來思考如何取得吃什麼東西的資料集合。

由於 Primary key 是以學員為維度,無法處理吃什麼這樣的維度,我們就可以透過 GSI 來處理這個查詢。

由於 GSI 可以有自己的分區鍵和排序鍵組合,因此在設計與應用上的邏輯,基本與 Primary key 一樣。

但一如 Primary key,透過 overloading 的方式來使用 PK 與 SK,GSI 在設計上也要考慮這個技巧,避免一個查詢維度就使用一個 GSI,既增加成本,也造成維護上的麻煩,更有可能隨著時間增加遇到 GSI 使用的上限(一張表 20 個)。

從關聯式思維轉換

對習慣了關聯式資料庫的開發者來說,DynamoDB 的主鍵設計需要思維轉換:

最重要的問題從「我的資料如何組織?」變成「我需要如何查詢這些資料?」,而且必須在資料表設計階段就決定好。

設計主鍵的建議

從查詢需求反推主鍵

先問自己:應用程式最常查什麼?單一值的查詢還是範圍查詢?

例如,單一值查詢(像統編)用 Partition Key 就夠;範圍查詢(像訂單日期)加個 Sort Key。

避免熱點

不要用低基數(low cardinality)的值當 Partition Key,例如 Status = “Active”,因為大部分資料會擠在同一個分區。

可以考慮把低基數值加到 Sort Key,或者用隨機後綴(例如 UserID#001)來分散資料。

掌握 Overloading 的技巧

Overloading 指的是在 Primary Key 中「塞進」多種資料類型,讓主鍵屬性承載多重實體。這樣做的目的是:

簡單來說,Overloading 就像是把多個「標籤」壓縮到同一個鍵裡,讓 DynamoDB 的查詢能力在有限結構下發揮最大效用。

把主鍵和資料的運用徹底切分

我們可以把一筆 item 拆成兩個部分,一部分是主鍵,一部分是資料,並且當作是不同的功能群組。

主鍵存在的目的是為了代表一組資料,以及操作該筆資料,以及透過 partition key 和 sort key 來查詢並產出一組 item collection。以房子來說,它就是門牌號碼,指出自己所在的位置,大多數的情況,它應該是不可變動的性質。

資料則是我們在應用程式中實際上要呈現的資訊,同樣的比喻,它是房子裡的房客,有可能搬出搬入,成員也有可能會變化,它是屬於可變動的性質。

很多時候,PK 與 SK 鍵可能會與資料中需要的欄位相同,例如我們 PK 鍵使用 email,或許就會覺得那我取得 PK 鍵就知道 email 了,不需要再資料欄位中多放一個 email 屬性,也可以節省一些資料空間。

但千萬不要這麼做,隨著資料成長,很多時候資料會有異動或是需要增加索引的情境,這時如果缺少資料的欄位,就會少了很大的彈性再做運用。對於需要 pre-join 來應付各種查詢情境而言,這樣的預留設計非常的重要。

因此在開發時,我們也會加上一些前綴詞,讓 key 的值徹底的與資料長得不同。

但更重要的是,在心裡把主鍵和資料當成兩邊互相看不到對方,將他們分別開來,key 是 key,data 是 data,在心裡默念一百遍。

使用主鍵的注意事項

結論

主鍵設計是 DynamoDB 開發的基石。好的主鍵設計使你的應用高效、可擴展,而糟糕的設計則可能導致性能問題和更高的成本。在設計應用時,首先明確你的資料訪問模式,然後據此設計你的主鍵結構。

記住,在 DynamoDB 中,主鍵不僅是識別數據的方式,更是檢索和資料數據的核心策略。


分享文章至:

上一篇文章
快速理解 DynamoDB 資料模型異動的策略