NoSQL Databaseでのキーの選択

主キーおよびシャード・キーはスキーマの重要な要素として、データへのアクセスと分散の効率化に役立ちます。

主キーとシャード・キーは、データ分散および簡単なアクセスにとって不可欠です。主キーとシャード・キーは、表を作成するときにのみ指定します。表の存続期間中はそのまま維持され、変更や削除はできません。

Oracle NoSQL表での主キーとシャード・キーの使用

主キー

表を作成するときには、1つ以上の主キー列を指定する必要があります。主キーは変更できず、表の有効期間中は存在します。主キーは、表のすべての行を一意に識別します。単純なCRUD操作の場合、Oracle NoSQL Databaseは、読取りまたは変更する特定の行を取得するために主キーを使用します。NoSQL Databaseの基礎となる記憶域はキー/値モデルに基づいているため、主キーを選択すると、特定の参照操作のパフォーマンスが大幅に向上する可能性があります。

シャード・キー

シャード・キーの主な目的は、スケーラビリティ実現のためにOracle NoSQL Databaseクラスタ全体にデータを分散し、かつ、参照しやすくするために、同じシャード・キーを共有するレコードを同じ物理ノード上にまとめることです。これらのレコードには、アトミックかつ効率的にアクセスできます。

アプリケーション開発時のキーの影響:

Oracle NoSQL Databaseでは、レプリケーション・ノードがグループ化されて、NoSQL Databaseクラスタのシャードを形成します。アプリケーションが特定のキーのレコードを取得するように要求すると、NoSQL Databaseドライバは、キーの一部(シャード・キーとして示される)をハッシュして、データを格納するシャードを識別します。シャードが識別されると、NoSQL Databaseドライバは、要求された一貫性レベルに応じて、シャード内の最適なレプリカからデータを読み取ることを選択できます。書込み操作については、NoSQL Databaseドライバは、常に書込みリクエストをシャードの動的に選択されたリーダー・ノードにルーティングします。したがって、ワークロード・スケーリングの観点からは、通常、このアーキテクチャはシャードを追加することでスケーリングされていると考えることができます。Oracle NoSQL Databaseでは、シャードを追加することで、クラスタのオンラインでのエラスティックな拡張をサポートしていますが、シャード・キーを適切に選択しないと、クラスタの拡張はソリューションのスケーリングに役立ちません。

主キーとシャード・キーをどのように設計するかは、システム・スループットのスケーリングと実現に大きく影響します。たとえば、レコード間でシャード・キーを共有すると、1つのアトミック操作で複数の表の行を削除することや、1つのアトミック操作で表の行のサブセットを取得することができます。シャード・キーを適切に設計すると、スケーラビリティが実現されるのみでなく、単一のシャードに対するデータの配置またはデータの取得に必要なサイクル数が減ることで、パフォーマンスを改善できます。シャード・キーでは、キー値の問合せを効率化するために、同じシャード上の記憶域を指定します。ただし、最適なパフォーマンスとスケーラビリティを実現するにはデータをシャード間で分散することが適切であるため、少数の一意の値を持つシャード・キーは避ける必要があります。

シャード・キーの選択時に考慮する重要な要素:
  • カーディナリティ: 低カーディナリティのフィールド・グループは、少数のシャードにまとめて格納されます。これらのシャードでは頻繁にデータ・リバランスを行う必要があるため、ホット・シャードの問題が発生する可能性が高くなります。一方、各シャード・キーのカーディナリティは高くなり、値が数100万個になることもあります。パフォーマンスと価値を最大限に高めるには、よりカーディナリティの高いフィールド(ID番号など)を選択して、数百万件のレコードに対応できるようにします。
  • 原子性:同じシャード・キーを共有するオブジェクトのみをトランザクションに含めることができます。複数のレコードにわたるACIDトランザクションの要件がある場合は、その要件を満たすことができるシャード・キーのみを選択します。
指針となるベスト・プラクティス:
  • シャード・キーの均一分散:操作は、1つのシャードの容量によって制限される可能性があります。シャード・キーが均一に分散されている場合、1つのシャードによってシステムの容量が制限されることはありません。値が均等に分散されることがわかっている1つ以上の列を選択することが理想的です。
  • 問合せの分離: スケーラビリティを最大化するには、問合せのターゲットを特定のシャードに限定します。問合せが単一のシャードに分離されていない場合、問合せはすべてのシャードに適用されます。これは効率性が低く、問合せレイテンシが増加します。問合せで単一のシャードに格納されたデータがフェッチされるようにします。シャード・キーを適切に設計し、単一のシャードからデータが取得されるようにすることでパフォーマンスを改善できます。シャード・キーでは、キー値の問合せを効率化するために、同じシャード上の記憶域を指定します。フィールド(アプリケーション問合せで頻繁に使用される)をシャード・キーとして指定します。

キー・サイズとキーのみのモデル化方法

Oracle NoSQL Databaseは、各表のキーをキャッシュします。そのため、キー・サイズはメモリーを効果的に使用するために重要なコンポーネントとなり、最終的には、Oracle NoSQL DatabaseがパフォーマンスSLAに対処できるかどうかを決定する要素となる可能性があります。したがって、サイズに関して可能なかぎり効率的な主キーを作成することが重要です。1秒当たり数百万の操作にわたって読取りと書込みのレイテンシを非常に低くする(1桁から2桁台前半のミリ秒)必要があるワークロードの場合、NoSQLのBツリーにキャッシュされたキーを活用することが、これらの厳しい要件を達成可能なアプリケーションを構築できるかどうかを左右する場合があります。さらに、他の方法ではキーにならない値をエンコードして主キーの一部とし、かつキーとNoSQL Databaseクラスタのサイズを慎重に設定することが可能な場合は、ACIDセマンティクスで維持されるメモリー・キャッシュされたBツリー・アクセス方法による非常に優れた利点を実現できます。高度に最適化され、レイテンシが非常に低いアプリケーションに関しては、Oracle NoSQLは、すべてをキーのみのデータとしてモデル化できるワークロードに対して、キーのみのアクセサを提供します。Oracle NoSQL Databaseは、キーのみのスキャンを実行するために、multiKetGeystableKeysIteratorなどの便利なキーのみのアクセスAPIを提供します。

データのキーのみのモデル化がアプリケーションに適しているかどうかを検討するときには、次のことを考慮してください。
  • レイテンシおよびスループットのSLA - キーのみのモデルを必要とする、非常に厳しいレイテンシおよびスループットのSLAはありますか。値の取得時にI/Oを実行する余裕はありますか。回転式ディスクでは値取得の平均レイテンシは15から30ミリ秒の範囲で、単一共有ディスク(SSD)ではこれは1から5ミリ秒の範囲である可能性があります。
  • 回転式ディスクとSSD - SSDの使用を検討していて、レイテンシSLAの対象の読取りが5ミリ秒の範囲内に問題なく収まる場合、そのアプリケーションに関してはキーのみのモデルを作成することに労力を費やす意味はない可能性があります。
  • コードの保守性と拡張性 - キーのみのモデル化により、コードのメンテナンス性と拡張性の潜在的なコストにおいて、パフォーマンス上の大きな利点がアプリケーションにもたらされます。値をキーにエンコードすることが、最終的には複雑で難解な戦略となる可能性があります。最終的に、開発および保守するコードが、キーのみのソリューションがもたらす利点に対して過度に複雑で難解かどうかを判断する必要があります。
  • データの正確なサイズ設定 - Oracle NoSQL Databaseクラスタを適切にサイズ設定できるように、キーのある程度正確なサイズ設定を導出することはできますか。キーのみのデータ・モデルの利点を活用するには、各レプリケーション・ノードのクラスタおよびキャッシュのサイズ設定が重要です。

キー列の順序付けおよび問合せ機能

Oracle NoSQL Databaseにおいて、キー列を宣言する順序は、部分的なキー参照問合せを満たすために重要です。これは、ストレージ・エンジンが基礎となるBツリーを管理する方法によるものです。コンポジット・キーは、キー宣言(主キーまたは索引キー)のDDLで指定された列を順序に従って連結したものと考えることができます。キーのDDLでの列の出現順序は、最も重要な列から最も重要でない列の順にすると考えてください。表にコンポジット主キー(複数の列を持つ主キー)がある場合、主キーは、各列の文字列表現を連結したものになります。この場合に問合せのパフォーマンスを改善するには、最も一般的に使用される問合せ列を、主キーで最も重要な列として指定することが重要です。

クラスタとOracle NoSQL Databaseキャッシュのサイズ設定方法を考える場合、重要な考慮事項は、キー・サイズの見積りを取得することです。Oracle NoSQLにより、ほとんどまたはすべての索引ノードをメモリーに保持できるようキャッシュのサイズを設定すると、アプリケーションで、パフォーマンス上の多数の利点を実現できます。キーのシリアライズ方法と永続的な格納方法を理解することは、より正確にサイズ設定を見積るために役立ちます。Oracle NoSQL Databaseでは、数値キーは圧縮された文字列値として格納されますが、文字列書式の場合は、ソート可能なままにしておく必要があります。つまり、数値キーは、キー文字列として表される場合、固定サイズである必要があります。シャード容量、シャード記憶域およびスループット容量の詳細と、シャードとマシンの合計を見積る方法については、「初期容量計画」を参照してください。

アイデンティティ列の使用かUUIDの使用かの選択

Oracle NoSQL Databaseによって値が自動的に割り当てられるように、列をIDENTITYとして宣言します。この場合、値は関連付けられた順序ジェネレータから生成されます。シーケンス・ジェネレータは、IDENTITY列の現在の値、次の値、および値の合計数を追跡するための、表のマネージャです。IDENTITY列をCREATE TABLE名前DDL文の一部として作成するか、ALTER TABLE名前DDL文を使用して既存の表にIDENTITY列を追加します。

汎用一意識別子(UUID)は、コンピュータ・システム内の情報を識別するために使用される128ビットの数値です。UUIDを作成し、それを使用して対象を一意に識別できます。Oracle NoSQLでは、UUID値はUUIDデータ型で表されます。UUIDデータ型はSTRINGデータ型のサブタイプとみなされます。UUID値は正規のテキスト形式で表示され、一般に、様々なSQLの演算子および式の文字列値と同じように動作するためです。表の列は、CREATE TABLE文で、型がUUIDであるとして宣言できます。アイデンティティ列はリージョン内のNoSQLクラスタ内でのみ一意であることが保証されるため、UUIDデータ型は、複数のリージョンにまたがる表のレコードに対してグローバルに一意の識別子が必要な場合に最適です。

表5-1 アイデンティティ列とUUID列の比較

アイデンティティ列 UUID列
Oracle NoSQLクラスタによって列に値が自動的に割り当てられるように、列をアイデンティティとして宣言します。 複数リージョン・システムでNoSQLクラスタ列に一意の値を割り当てる必要がある場合は、列をUUIDとして宣言します。
表内のINTEGER、LONG、またはNUMBER列は、アイデンティティ列として定義できます。 UUIDはSTRINGデータ型のサブタイプです。
アイデンティティ列は、GENERATED ALWAYSまたはGENERATED BY DEFAULTのいずれかとして定義できます。 UUID列はGENERATED BY DEFAULTとして定義することも、データの挿入または更新時に文字列の値を指定することもできます。

対応するUUID列よりも記憶域のコストが少なくなります。

LONGが主キーの場合、最大で10バイトのコストがかかります。LONGが主キー以外の場合、最大で8バイトのコストがかかります。

対応するアイデンティティ列よりも記憶域のコストが多くなります。

UUID値が主キーの場合、19バイトのコストがかかります。UUID値が主キー以外の場合、16バイトのコストがかかります。

アイデンティティ列を使用すると、Oracle NoSQLで、単一のリージョン内で値を自動的に割り当てることができます。アイデンティティ列がマルチリージョン・デプロイメントで使用されている場合は、エラーがスローされます。

UUID列を使用すると、Oracle NoSQLで、複数のリージョンにわたりグローバル値を自動的に割り当てることができます。これは、マルチリージョン・デプロイメントで役立ちます。UUID列は、アイデンティティ列よりも大きくなります。