共用方式為


在 Azure Cosmos DB for PostgreSQL 中建立多租用戶 SaaS 應用程式的模型

適用於: Azure Cosmos DB for PostgreSQL (由 PostgreSQL 的超大規模 (Citus) 資料庫延伸模組提供)

租用戶識別碼作為分區索引鍵

租用戶識別碼是位於工作負載的根目錄的資料行,或是資料模型中的階層頂端。 例如,在此 SaaS 電子商務結構描述中,它會是商店識別碼:

數據表圖表,其中醒目提示store_id數據行。

此資料模型通常適用於 Shopify這類的企業。 它會裝載多個線上商店的網站,其中每個商店都會與自己的資料互動。

  • 此資料模型具有許多資料表:商店、產品、訂單、明細項目和國家/地區。
  • 商店資料表位於階層的頂端。 產品、訂單和明細項目皆與商店相關,因此位於較低階層。
  • 國家/地區資料表與個別商店無關,而是在各個商店之間。

在此範例中,位於階層頂端的 store_id 是租用戶的識別碼。 這是正確的分區索引鍵。 挑選 store_id 作為分區索引鍵可讓單一商店的單一員工在所有資料表之間收集資料。

依商店共置資料表有許多優點:

  • 提供 SQL 涵蓋範圍,例如外部索引鍵和聯結。 單一租用戶的交易會在每個租用戶存在的單一背景工作角色節點上進行當地語系化。
  • 效能可達到個位數毫秒。 單一租用戶的查詢會路由傳送至單一節點,而不是平行處理,這有助於最佳化網路躍點,並且仍能調整計算/記憶體。
  • 可縮放規模。 隨著租用戶數增加,您可以新增節點,並將租用戶重新平衡到新的節點,或甚至將大型租用戶隔離到他們自己的節點。 租用戶隔離可讓您提供專用資源。

共置至相同節點的數據表圖表。

多租用戶應用程式的最佳資料模型

在此範例中,我們應該依商店識別碼散發商店專用的資料表,並讓 countries 作為參考資料表。

store_id更普遍醒目提示的數據表圖表。

請注意,租用戶專用資料表具有租用戶識別碼且已散發。 在我們的範例中,會散發商店、產品和明細項目。 其餘資料表為參考資料表。 在範例中,國家/地區資料表為參考資料表。

-- Distribute large tables by the tenant ID

SELECT create_distributed_table('stores', 'store_id');
SELECT create_distributed_table('products', 'store_id', colocate_with => 'stores');
-- etc for the rest of the tenant tables...

-- Then, make "countries" a reference table, with a synchronized copy of the
-- table maintained on every worker node

SELECT create_reference_table('countries');

大型資料表皆應有租用戶識別碼。

  • 如果您要移轉現有的多租用戶應用程式至 Azure Cosmos DB for PostgreSQL,您可能需要將租用戶識別碼資料行反正規化,並在資料有所遺漏時,將其新增至大型資料表,然後回填該資料行的遺漏值。
  • 對於 Azure Cosmos DB for PostgreSQL 上的新應用程式,請確定租用戶識別碼存在於所有租用戶專用的資料表上。

請務必在分散式資料表的主索引鍵、唯一索引鍵和外部索引鍵條件約束上,以複合索引鍵的形式包含租用戶識別碼。 例如,如果資料表的主索引鍵為 id,請將它轉換成複合索引鍵 (tenant_id,id)。 但您不需要變更參考資料表的索引鍵。

最佳效能的查詢考量

以租用戶識別碼篩選的分散式查詢在多租用戶應用程式中執行的效率最佳。 請確定您的查詢範圍一律限定為單一租用戶。

SELECT *
  FROM orders
 WHERE order_id = 123
   AND store_id = 42;  -- ← tenant ID filter

即使原始篩選條件明確識別您想要的資料列,您仍需新增租用戶識別碼篩選條件。 租用戶識別碼篩選條件看似多餘,但會告訴 Azure Cosmos DB for PostgreSQL 如何將查詢路由傳送至單一背景工作角色節點。

同樣地,當您聯結兩個分散式資料表時,請確定這兩個資料表的範圍都限定為單一租用戶。 您可以藉由確保聯結條件包含租用戶識別碼來進行範圍設定。

SELECT sum(l.quantity)
  FROM line_items l
 INNER JOIN products p
    ON l.product_id = p.product_id
   AND l.store_id = p.store_id   -- ← tenant ID in join
 WHERE p.name='Awesome Wool Pants'
   AND l.store_id='8c69aa0d-3f13-4440-86ca-443566c1fc75';
       -- ↑ tenant ID filter

對於幾個常用的應用程式架構,有數個協助程式程式庫可以讓您輕鬆地在查詢中包含租用戶識別碼。 請參閱以下指示:

下一步

現在,我們已完成探索可調整應用程式的資料模型化。 下一步是使用您選擇的程式設計語言來連結和查詢資料庫。