シャードキーの選択:カーディナリティ、頻度、単調性
3つの観点(カーディナリティ、書き込み分散、クエリのターゲティング)でシャードキー候補を評価し、ホットシャードのアンチパターンを回避します。
「シャードキーの選択:カーディナリティ、頻度、単調性」は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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- シャーディングの概念:チャンク、バランサー、シャードキー
- シャードキーの選択:カーディナリティ、頻度、単調性
- レンジシャーディングとハッシュシャーディングの戦略
- ゾーンシャーディング:データのリージョン固定