MongoDB Academy · レッスン

シャードキーの選択:カーディナリティ、頻度、単調性

3つの観点(カーディナリティ、書き込み分散、クエリのターゲティング)でシャードキー候補を評価し、ホットシャードのアンチパターンを回避します。

レッスン 2/413 ステップ

「シャードキーの選択:カーディナリティ、頻度、単調性」はCoddyKit上の無料MongoDB Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはMongoDB Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 MongoDB Academyコースには全4レッスンが含まれています。

シャードキーの選択が重要な理由

シャードキーは一度設定すると不変であり、コレクション全体のシャーディング解除と再シャーディングを行わない限り変更できません。これはコストが高く、システムに大きな影響を与える操作です。誤ったシャードキーを選ぶと、ホットシャード、低品質なクエリルーティング、ハードウェアの無駄が生じます。候補は、カーディナリティ、頻度、単調性という3つの観点で評価する必要があります。

カーディナリティ:異なる値はいくつあるか

カーディナリティとは、シャードキーが取り得る異なる値の数です。カーディナリティが高い(例:userId、email、orderId)ことは望ましい状態です。MongoDBが設定できるチャンク境界の候補が増え、バランサーがデータを細かく分散できるためです。カーディナリティが低い場合(例:status: 'active' | 'inactive'、50種類の値を持つcountry)は、分割も移行もできないジャンボチャンクが発生します。

// HIGH cardinality — good shard key
sh.shardCollection('mydb.users', { userId: 1 })

// LOW cardinality — avoid: only 2 chunk boundaries possible
sh.shardCollection('mydb.users', { status: 1 }) // BAD

頻度:値はどの程度均等に分散しているか

頻度は、各シャードキー値を共有するドキュメント数を表します。カーディナリティが高くても、少数の値がドキュメントの大部分に現れる場合は問題になります。たとえば、countryCodeフィールドに200種類の値があっても、ユーザーの90%が1つの国に集中していると、分割できない巨大なホットチャンクが発生します。

// Estimate frequency distribution before choosing
db.users.aggregate([
  { $group: { _id: '$countryCode', count: { $sum: 1 } } },
  { $sort: { count: -1 } },
  { $limit: 10 }
])
// If top 1 value has 80%+ of docs, this is a bad shard key

単調性:値は常に増加しているか

単調性とは、シャードキーの値が時間の経過とともに常に増加(または減少)するかどうかを指します。createdAtのタイムスタンプやObjectId(_id)のようなフィールドは単調増加します。これは、すべての新しい挿入が1つのシャード上にある同じ「最大値」チャンクに配置されるため問題になります。過去のデータが均等に分散されていても、書き込みホットスポットが発生します。

// Monotonic keys cause write hot spots
// All new orders go to the shard with the latest date range
sh.shardCollection('mydb.orders', { createdAt: 1 }) // BAD for high insert rate

// Fix: use hashed sharding to spread monotonic keys
sh.shardCollection('mydb.orders', { createdAt: 'hashed' })

理想的なシャードキーの特性まとめ

理想的なシャードキーには、次の特性があります。高いカーディナリティ — 数千または数百万の異なる値があること。頻度の偏りが小さい — 特定の1つの値に集中しないこと。単調でない分布 — 値が常に増加しないこと、またはハッシュシャーディングを使用すること。クエリとの整合性 — 頻度が高く、レイテンシーが重要なクエリで使われるフィルターと一致し、ターゲットルーティングが可能であること。

複合シャードキー

複合シャードキーは、分布を改善するために2つのフィールドを組み合わせたものです。たとえば、{ tenantId: 1, createdAt: 1 }はテナント間で分散し(高いカーディナリティ)、各テナント内では範囲クエリを可能にします。最初のフィールドが大まかな分散を決め、2番目のフィールドがより細かな分割を行います。複合キーを使うと、複数フィールドのクエリ条件をターゲットクエリとして処理できます。

// Compound shard key: tenant + date
sh.shardCollection('mydb.events', { tenantId: 1, createdAt: 1 })

// This query is fully targeted (both shard key fields present)
db.events.find({ tenantId: 't123', createdAt: { $gte: ISODate('2025-01-01') } })

ハッシュシャードキー

ハッシュシャードキーでは、フィールド値をチャンクに対応付ける前にハッシュ関数を適用します。これにより、ObjectIdのような単調増加するキーがランダムに分散されたハッシュ値に変換され、書き込みホットスポットが解消されます。一方、ハッシュ値は元の順序で保存されないため、そのフィールドに対する範囲クエリはScatter-Gatherになります。

// Hashed sharding: uniform write distribution
sh.shardCollection('mydb.events', { _id: 'hashed' })

// Range query on _id is now scatter-gather (con)
// But all inserts are evenly distributed (pro)

地理的分散のためのゾーンシャーディング

MongoDBでは、タグ(ゾーン)を使ってシャードキーの範囲を特定のシャードに割り当てるゾーンシャーディングが可能です。これはデータレジデンシー要件に役立ちます。たとえば、ヨーロッパのユーザーデータをEUリージョンのシャードに、米国のデータを米国のシャードに固定できます。ゾーンシャーディングには、最初の構成要素としてリージョンのプレフィックスを持つ複合シャードキーが必要です。

// Tag shards with zones
sh.addShardTag('shard01', 'EU')
sh.addShardTag('shard02', 'US')

// Assign key ranges to zones
sh.addTagRange('mydb.users',
  { region: 'EU', userId: MinKey },
  { region: 'EU', userId: MaxKey },
  'EU'
)

候補を評価する:実践的なチェックリスト

シャードキーの候補を評価するときは、次の手順を実行します。1) カーディナリティを確認します。db.col.distinct('field').lengthは数千以上になることが望ましいです。2) 集計を使って頻度分布を確認します。3) フィールドが単調性を持つかどうか(タイムスタンプ、自動インクリメントなど)を判断します。4) 最も頻繁に実行される上位5つのクエリを確認し、候補フィールドがフィルターに含まれているかを調べます。

// Quick cardinality check
db.events.distinct('userId').length   // want > 10,000+

// Frequency check — any value > 1% of docs is a risk
const total = db.events.countDocuments()
db.events.aggregate([
  { $group: { _id: '$userId', n: { $sum: 1 } } },
  { $match: { n: { $gt: total * 0.01 } } }
])

_idフィールドをハッシュシャードキーとして使用する

多くのワークロードにおいて、一般的で安全なデフォルト設定は{ _id: 'hashed' }を使用することです。MongoDBのObjectId値は単調増加しますが、ハッシュ化すると均等に分散されます。これにより、すぐに均一な書き込み分布を実現できます。主な制限は、_idに対する範囲クエリがScatter-Gatherになることですが、ほとんどのドキュメント単位の検索ワークロードでは許容できます。

// Safe default for write-heavy workloads without range queries
sh.shardCollection('mydb.messages', { _id: 'hashed' })

// Single-document lookup by _id is still targeted
// (hash is deterministic: mongos knows which shard)
db.messages.findOne({ _id: ObjectId('...') })

Atlasでのシャードキー選択

MongoDB Atlasでは、Performance AdvisorにShard Key Advisorが用意されています。これはクエリパターンを分析し、実際の使用状況に基づいてシャードキーを推奨します。単調増加するキー、頻度の偏り、インデックスの不足を検出できます。シャーディングの前にAdvisorを使用すると、クエリパターンがすでに確立されている本番ワークロードで特に役立ちます。

クイックチェック

このレッスンで学んだMongoDBとNoSQLデータベースの概念について、理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、優れたシャードキーは高いカーディナリティと小さな頻度の偏りを持ち、単調な値を避けること、複合シャードキーは分散とクエリのターゲット化の両方を実現すること、そしてハッシュシャーディングは範囲クエリの効率を犠牲にして、単調なキーによるホットスポットを解消することを学びました。次は、範囲シャーディングとハッシュシャーディングの戦略を詳しく比較します。

無料で開始

AI チューターと学ぶ JavaScript — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
30
レッスン
120

よくある質問

「シャードキーの選択:カーディナリティ、頻度、単調性」レッスンは無料ですか?

はい。「シャードキーの選択:カーディナリティ、頻度、単調性」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、MongoDB Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 MongoDB Academyコースには全4レッスンが含まれています。

「シャードキーの選択:カーディナリティ、頻度、単調性」で何を学びますか?

3つの観点(カーディナリティ、書き込み分散、クエリのターゲティング)でシャードキー候補を評価し、ホットシャードのアンチパターンを回避します。 ブラウザで直接実行するハンズオンコードでMongoDB Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

MongoDB Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのMongoDB Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「シャードキーの選択:カーディナリティ、頻度、単調性」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このMongoDB Academyレッスンでコードを書いて実行できますか?

はい。すべてのMongoDB Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. シャーディングの概念:チャンク、バランサー、シャードキー
  2. シャードキーの選択:カーディナリティ、頻度、単調性
  3. レンジシャーディングとハッシュシャーディングの戦略
  4. ゾーンシャーディング:データのリージョン固定
← MongoDB Academyに戻る