WEB問題集
Azure Cosmos DB for NoSQL でコンテナーのパーティション キーを選定するとき、最も重視すべき特性として正しいものはどれですか?
解説
【正解: D】の理由
良いパーティション キーは、取り得る値の種類が多い高カーディナリティの属性であることが重要です。値の種類が多いほど、データと要求 (RU/s の消費) を多数の論理パーティションへ均一に分散でき、ストレージやスループットが特定のパーティションに偏るのを防げます。これによりホット パーティションの発生を避け、コンテナー全体でスケールアウトを最大限に活かせます。加えて、パーティション キーの値は項目の作成後に変更できないため、頻繁に変化しない安定した属性を選ぶ必要があります。読み取りクエリのフィルター条件と一致させれば、単一パーティションで完結するクエリになり RU コストも抑えられます。1 つの論理パーティションには 20 GB の上限があるため、この点でも高カーディナリティが有利です。
【他選択肢が違う理由】
- A: パーティション キーの値は作成後に変更できないため、頻繁に更新されて値が変化する属性はキーとして不適切です。
- B: 取り得る値が 2〜3 種類しかない低カーディナリティでは、少数の論理パーティションに集中しホット パーティションを招きます。
- C: 全ドキュメントが同一値だと論理パーティションが 1 つになり、20 GB の論理パーティション上限に達してスケールできません。
【参考】
Azure Cosmos DB for NoSQL で、単一の論理パーティションにスコープした効率的なクエリを記述します。各ドロップダウンで適切な値を選択してください。
SELECT * FROM c
WHERE c.{{BLANK1}} = "tenant-01"
AND c.status = {{BLANK2}}| ステートメント | 選択 |
|---|---|
|
BLANK1: 単一パーティション クエリにするため等値フィルターするパーティション キーのプロパティ
|
|
|
BLANK2: status を文字列リテラルで等値比較する値
|
解説
【正解マッチング】
| 判定対象 | 正解 |
|---|---|
| BLANK1: 単一パーティション クエリにするため等値フィルターするパーティション キーのプロパティ | partitionKey |
| BLANK2: status を文字列リテラルで等値比較する値 | "active" |
【ポイント】
「BLANK1: 単一パーティション クエリにするため等値フィルターするパーティション キーのプロパティ」→ partitionKey: パーティション キーのプロパティを等値 (=) でフィルターすると、クエリが単一論理パーティションにスコープされ RU を節約できます。「BLANK2: status を文字列リテラルで等値比較する値」→ "active": NoSQL の文字列リテラルは二重引用符で囲み、status = "active" のように等値比較します。「パーティション キーを等値フィルターするとクロスパーティション クエリを避けられるか」→ はい: パーティション キーを等値で指定すると単一パーティションへルーティングされ、クロスパーティション (ファンアウト) を回避できます。
【参考】
階層パーティション キーを設計・適用する手順を順序通りに並べてください。
- kind を MultiHash にして階層キーを指定しコンテナーを作成
- 単一キーでは 20 GB 上限を超えるテナント等の高基数パーティションを特定
- 上位レベル (例 TenantId) と下位レベル (例 UserId) を最大 3 レベルで定義
- 上位レベルでの等値フィルター クエリが対象パーティションに絞られるか検証
解説
【正しい順序】
- 単一キーでは 20 GB 上限を超えるテナント等の高基数パーティションを特定
- 上位レベル (例 TenantId) と下位レベル (例 UserId) を最大 3 レベルで定義
- kind を MultiHash にして階層キーを指定しコンテナーを作成
- 上位レベルでの等値フィルター クエリが対象パーティションに絞られるか検証
【ポイント】
- ステップ 1 上限超過の特定: 単一キーで上限超過する対象を特定します。
- ステップ 2 レベル定義: 上位/下位レベルを最大 3 レベルで決めます。
- ステップ 3 コンテナー作成: MultiHash で階層キーを指定し作成します。
- ステップ 4 検証: 上位レベル フィルターの効率を確認します。
【誤った順序の問題点】
- レベル定義の前にコンテナーを作成する: 階層レベルが決まっていないと正しい paths/kind を指定できません。
- 上位レベル フィルターの検証を省略: 上位プレフィックスで絞り込めるか確認しないと、フルファンアウトが残る可能性があります。
【参考】
Cosmos DB for NoSQL での非正規化 (denormalization) の適用について、正しい説明を選択してください。
解説
【正解: A / C / E】の理由
非正規化 (denormalization) は、頻繁に一緒に読まれる項目を別エンティティから複製・埋め込みして保持し、JOIN や追加クエリを避けて読み取りを最適化する手法です (E)。読み取り負荷が高いシステムでは、参照によるラウンドトリップを減らせるため、書き込み時に複製を維持するコスト増と引き換えに読み取り性能を大きく改善できます (A)。ただし、複製したコピーは自動では同期されないため、元データが更新された際にすべてのコピーを整合させる仕組み、たとえば変更フィード (Change Feed) を用いた伝播などを併せて設計する必要があります (C)。非正規化は読み取り最適化のトレードオフとして、読み取り頻度が書き込み頻度を上回るデータに対して選択的に適用するのが定石です。
【他選択肢が違う理由】
- B: 非正規化はデータを意図的に複製する手法であり、ストレージ消費はむしろ増え、データの重複が解消されるわけではありません。
- D: 複製したコピーは強整合で自動同期される仕組みを持たず、変更フィードなどでアプリ側が整合を取る必要があります。
【参考】
各 RU コスト要素を説明にマッチさせてください。
- フィルター述語の選択性
- 読み書きする項目のサイズ
- クエリの複雑さ/結果件数
- インデックス作成ポリシー
解説
【正解マッチング】
| 項目 | 説明 |
|---|---|
| 読み書きする項目のサイズ | 項目サイズに比例して増える要素 |
| クエリの複雑さ/結果件数 | クエリ効率に依存する要素 |
| フィルター述語の選択性 | クエリ効率に依存する要素 |
| インデックス作成ポリシー | 書き込み時の処理に影響する要素 |
【ポイント】
RU (要求ユニット) は Cosmos DB の操作コストを正規化した通貨で、複数の要因で消費量が決まります。読み書きする項目のサイズは、大きなアイテムほど読み取り・書き込みに必要な処理量が増えるため、項目サイズにおおむね比例して RU が増える要素です。クエリの複雑さや結果件数は、スキャンする項目数・返す件数・関数やソートの有無によって実行コストが変わるため、クエリ効率に依存する要素です。フィルター述語の選択性も、選択性が高くインデックスで絞り込めるほど読み取る項目が減り、逆に選択性が低いと多くの項目を処理するため、同じくクエリ効率に依存します。インデックス作成ポリシーは、包含パスが多いほど書き込みのたびに更新すべきインデックス エントリが増えるため、書き込み時の処理コストに影響する要素です。要因を理解して RU を最適化するのが設計の要点です。
