cosmic

Cosmos DBでデータモデリングをする際には、アクセスパターンに基づいてします。

  1. 最初にアクセスパターンを特定します
  2. 特定したアクセスパターンに基づいて、データモデルをデザインします

これは、データモデリングをアクセスパターンに最適化させるためです。

パーティショニングは、全体的な性能、拡張性、費用の観点から重要なポイントです。
詳細は、

http://aka.ms/PracticalCosmosDB

が参考になります。

パーティショニングの選択を間違えた場合は、Change Feed経由でマイグレーションをします。
適切なパーティショニングなっているかは、パーティションを監視することが重要です。

image

cosmic

Cosmos DB の重要機能に、Change Feedがあります。
Change Feedは、API経由で全てのSocmos Containerに提供されます。
Change FeedはAzure FunctionsやCosmos DB SDKを使用する任意のコードから利用できます。

使用例を考えてみましょう。

  1. 異なる/複数のパーティションキー用に他のコンテナーに複製する
  2. コンテナー間の非正規化
  3. イベントドリブン アーキテクチャ用のトリガーAPI
  4. リアルタイムのストリーム処理とマテリアライズビュー用
  5. セカンダリデータストアへのデータの移動やアーカイブ

image

CosmosDB

Cosmos DB でデータをモデル化する方法として、参照モデルと埋め込みモデルの2種類があります。
参照モデルがいわゆる、リレーショナルデータベースでの正規化をベースとしたモデリングとなります。

参照モデルとしては、種類ごとにドキュメントを分離し、1つのPostに複数のCommentが紐づいたりします。
それぞれが独立していて、個別に更新されます。

それに対して、埋め込みモデルは、1つのドキュメントに複数のデータを内在させます。
1つのPostに複数のCommentを内在させます。
内在しているので、Itemを更新すると同時に更新することになります。

Cosmos DBで性能とRU/sを考慮したモデルリングをしていく際には、埋め込み型を使用したほうがいいケースがあり、モデルリング時にはどちらが最適化を考慮する必要があります。

image

cosmic

データモデルを設計する方法として、従来からあるのがリレーショナルな方法です。
一つのエンティティを一つのテーブルに入れて、一つのコンテナーに格納する方法です。
しかし、これはCosmos DBの場合は非効率になるケースが多々あります。

Cosmos DB らしい設計をするには、「type」プロパティを持たせて、種類はプロパティで表現します。
PostとCommentsは同じPostIdでパーティショニングして、同じコンテナーに格納させるべきです。

postもcommentsも同じコンテナーに格納し、区別はtypeでします。

コンテナーに複数のEntityタイプを格納することは、Cosmos DBの場合良い設計になることが多いです。
スキーマーに依存しないCosmos DB標準のレバレッジをかけられ巣。
類似したパターンを共有し、同じパーティションキーで一つのクエリにすることでRU/sを削減できます。

FYI: CosmosDB のデータモデリングの勘所

image

cosmic

元記事:Troubleshoot query performance for Azure Cosmos DB

  1. DBとクライアントは同じリージョンに配置する。
  2. 一貫性レベルを確認する。
    許容できる一貫性レベルを確認する。
  3. ログクエリ情報を使用する。
    QueryMetricsを使用して、遅い・重いクエリを直す
  4. Query Optionの調整
    クエリ性能はリクエストのFeed Optionパラメータで調整できる
    Max Degree of Parallelism (-1)
    Max Buffered Item Count (-1)
    Max Item Count (-1)
    比較するときとは、2,4,8,16のような値を使用する
  5. コンテナーからすべての結果を読む
    全ての結果を取得できるまで取得し続けてください。
    継続トークンがある間は取得し続ける。
  6. インデックスを使用できるシステム関数を選ぶ
    文字列範囲に変換できる式は、インデックスを使用できます。
    STARTSWITH / LEFT / SUBSTRING
  7. JOIN式の最適化
    JOIN式は大きなクロス積に拡張できます。
    可能であれば、フィルタをして狭い範囲に対してクエリを実行します。
  8. order by の最適化
    order by 性能は、分散度が低い列かインデックスポリシーがない列だと、性能劣化します。
  9. 多くの大きなItemを読み込んだり実行する
    時間とRUsは、レスポンスサイズとクエリ処理の作業量に依存します。

image