配列のシリアルに関しては、はい、そのとおりです。
「port_number」を選択すると、カーディナリティが十分に高くなり、同じ「port_number」を持つすべてのドキュメントが同じチャンクに存在することを意味しますが、ポートの範囲に対してクエリが到着すると、複数のヒットになります破片。
ご想像のとおり、正しいシャード キーを選択することは非常に重要で困難です。「完全な」シャード キーは、相互に排他的な 3 つの目標を満たします。
- 書き込みはシャード全体に均等に分散する必要があります
- 個々のドキュメントのクエリは、シャード全体に均等に分散する必要があります
- 範囲クエリと並べ替えは効率的である必要があります。つまり、シーケンス内の要素はすべて同じシャードにある必要があります。
シーケンシャル シャード キーを避ける理由の 1 つは、挿入時にホットスポットが作成されることです。常に、単一のシャードがすべての挿入負荷を処理します (これは、クエリの分離には適していますが、最終的にはパフォーマンスには適していません。したがって、_id と "datetime " は良い選択ではありません)。複合シャードキーを使用する可能性があります。このトピックについては、Google グループでいくつかの良い議論があります。
{ array_serial : 1 , datetime : 1 } のようなものを選択すると、「array_serial」のデータは、必要に応じて (日時に基づいて) 多くのチャンクに分割され、サーバー全体に分散されます。完全な「datatime」値を使用します。
「array_serial」はどのように決定されますか? 値の範囲は?port_number が変わると port_name も変わると思いますか?
あなたが言ったことを考えると、私はおそらく { port_number : 1, datetime: 1} を選ぶでしょう。それは完璧ではありませんが、悪くはありません。
それはあなたにとって最良の選択ですか?それは本当に使用情報に依存します。
特定のポート番号範囲内で特定の名前のクエリを実行することが多い場合は、これが最適なキーになる可能性があります。
一方、ポート番号に関係なく、日時に基づいてすべての「名前」のクエリをほとんど実行する場合は、毎回スキャッター/ギャザー クエリを実行することになり、クラスターの全体的なパフォーマンスが低下します。
さらに、自問自答する
1 つのシャードですべての挿入を処理できますか?
範囲クエリのパフォーマンスは本当に重要ですか?
あなたの質問に基づいて、シャードキーの選択に関するリンクをすでに読んでいると思います:)
役立つ可能性のある適切なシャード キーの選択に関する詳細な議論を以下に示します。