提供された情報に基づいて、いくつかのスキーマ設計を選択できます (例として JSON を使用)。複数の戦車が 1 つのマップに存在する可能性があり、マップ データは 1 つのマップにしかリンクされていないなど、いくつかの仮定を立てました。必要に応じて微調整する必要があります。また、すべてのソリューションの長所と短所をいくつか提供しようとしています。
オプション #1 (単一コレクション)
これは最も簡単なはずですが、最善の解決策ではありません。ここでは、極端な「非正規化」を使用してすべてを 1 つのドキュメントにまとめます。
{
"mapname": "map1",
"mapfile": "mapfile1",
"data": {
"rank": "rank1",
"color": "color1",
...
"tanks": [
{
"name": "tank1",
...
"user": {
"name": "user1",
...
}
},
{
...
}
]
}
}
このソリューションは、多くの書き込み、まれな更新、およびすべての情報をまとめたい読み取りを行う場合に最適です。一方で、ユーザー情報をアプリケーション データに直接保存するなど、多くの欠点があります (パスワード ハッシュがその例です)。
オプション #2 (2 つのコレクション)
ユーザー データを 1 つのコレクションに入れ、他のデータを 2 番目のコレクションに入れます。
ユーザー コレクション
{
"id": 1,
"username": "user1",
"password": "passwordhash",
...
}
データ収集
{
"mapname": "map1",
"mapfile": "mapfile1",
"data": {
"rank": "rank1",
"color": "color1",
...
"tanks": [
{
"name": "tank1",
...
"user": userId
}
},
{
...
}
]
}
}
このオプションは、最初のオプションよりもはるかに優れています。まず、機密性の高いユーザー データ (パスワードのハッシュなど) を他のデータと一緒にコレクションに含めたくありません。また、不要なフィールドの多くをスキップすることなく、必要な情報を取得するだけなので、これはユーザー オブジェクトの読み取りにも適しています。短所は、タンク オブジェクトへの大量の書き込み操作が問題になる可能性があることです。
オプション #3 (3 つのコレクション)
次のステップは、タンクをデータ コレクションから独自のコレクションに移動することです。
ユーザー コレクション
{
"id": 1,
"username": "user1",
"password": "passwordhash",
...
}
戦車コレクション
{
"name": "tank1",
...
"user": userId
}
データ収集
{
"mapname": "map1",
"mapfile": "mapfile1",
"data": {
"rank": "rank1",
"color": "color1",
...
"tanks": [
idOfTank1,
idOfTank2,
...
]
}
}
これは、タンクなどの単一オブジェクトの書き込みが多く、コレクションからタンクを読み取る場合に最適です。このソリューションには、たとえばマップとそのマップ内のすべての戦車を取得する場合など、大量のデータを一緒に読み取る場合に問題があります。その場合、タンクとマップ データの依存関係を解決する必要があります。
概要
ご覧のとおり、ドキュメント指向のデータベースではスキーマの設計は容易ではありません。これが、クエリ パターンを求めた理由です。優れた設計を考え出すには、ほとんどのクエリ パターンを事前に知っておく必要があります。開始するには、理にかなっていると思われる設計で単純なプロトタイプを作成し、いくつかのテスト データを使用してクエリ パターンをテストする必要があります。それが機能する場合は、小さな変更を加えてパフォーマンスをさらに向上させることができます。そうでない場合は、クエリ パターンを再考し、より良い設計がどのように見えるかを考え直してください。そのために本格的なアプリケーションは必要ないことに注意してください。そのほとんどは、たとえば MongoDB の管理シェルや DocumentDB の場合の単純なコンソール アプリケーションを使用して、1 行のコードを記述する前にテストできます。