シャード・テーブル (およびシャード化されていないテーブル) は、任意のノードのクラスタ・ネームスペースで、シャーディング仕様を含む SQL CREATE TABLE 文を使用して作成できます。このシャーディング仕様は、テーブルがシャーディングされること、および使用されるシャード・キー (シャード・テーブルのどの行をどのシャードに格納するかを特定するフィールド) を示します。シャード間でテーブルの行を均等に分散するための確実な方法を提供する適切なシャード・キーでテーブルが作成されると、INSERT や専用ツールを使用してここにデータをロードできます。
シャード・キーの選択
既定では、シャード・テーブルを作成してシャード・キーを指定していない場合、システムにより割り当てられた RowIDOpens in a new tab をシャード・キーとして使用して、データがここにロードされます。例えば、2 つのシャードがある場合、RowID=1 の行は一方のシャードに、RowID=2 の行はもう一方のシャードにロードされます。これはシステムが割り当てたシャード・キー (SASK) と呼ばれ、データの均等分散を最適に保証し、最も効率的な並列データ・ロードを可能にするため、多くの場合、最も簡単で効果的なアプローチになります。
Note:
既定では、RowID フィールドは ID と名付けられ、列 1 に割り当てられます。ID というユーザ定義フィールドが追加されると、テーブルのコンパイル時に RowID フィールドは ID1 という名前に変更され、キーを指定せずにシャーディングを行う際、既定で使用されるのは、このユーザ定義の ID フィールドになります。
シャード・テーブルの作成時に、シャード・キーとして 1 つ以上のフィールドを指定するオプションもあります。これはユーザ定義のシャード・キー (UDSK) と呼ばれます。スキーマに RowID に対応しない意味的に重要な一意の識別子が含まれている場合、例えば、スキーマ内のいくつかのテーブルに accountnumber フィールドがある場合は、UDSK を使用する良い機会かもしれません。
その他の考慮事項として、大きなテーブルを結合するクエリがあります。各シャード・クエリはシャードローカル・クエリに分解されます。それぞれのクエリは個々に、各シャード上でローカルに実行され、そのシャードに存在するデータを参照すればよいだけです。ただし、シャード・クエリに 1 つ以上の結合が含まれる場合、シャードローカル・クエリは一般に他のシャードのデータを参照する必要があるため、処理時間が長くなると共に、データベース・キャッシュに割り当てられたメモリをより多く使用します。この余分なオーバーヘッドは、コシャード結合を有効にすることで回避できます。コシャード結合では、結合される 2 つのテーブルの行が同じシャード上に配置されます。結合がコシャードされている場合、その結合が関与するクエリは、同じシャード上の行のみを結合するシャードローカル・クエリに分解され、他のシャード・クエリと同様に個別にローカルに実行されます。
コシャード結合は、以下の 2 つのアプローチのいずれかを使用して有効にできます。
同等な UDSK を使用するには、2 つのテーブルにシャード・キーとして頻繁に結合されるフィールドを指定するだけです。例えば CITATION テーブルと VEHICLE テーブルを結合し、各車両に関連付けられた交通違反通知を返す場合、以下のようにします。
SELECT * FROM citation, vehicle where citation.vehiclenumber = vehicle.vin
この結合をコシャード結合にするには、同等なそれぞれのフィールドをシャード・キーとして使用して、両方のテーブルを作成します。
CREATE TABLE VEHICLE (make VARCHAR(30) not null, model VARCHAR(20) not null,
year INT not null, vin VARCHAR(17) not null, shard key (vin))
CREATE TABLE CITATION(citationid VARCHAR(8) not null, date DATE not null,
licensenumber VARCHAR(12) not null, plate VARCHAR(10) not null,
vehiclenumber VARCHAR(17) not null, shard key (vehiclenumber))
シャーディング・アルゴリズムは決定的であるため、特定の VIN の VEHICLE 行と CITATION 行 (ある場合) (それぞれ vin および vehiclenumber フィールドの値) は、同じシャード上に配置されます (ただし、フィールド値そのものが、行の各セットがどのシャードに配置されるかを特定することはありません)。したがって、上記のクエリが実行されると、各シャードローカル・クエリは、ローカルに (つまり、完全にそのシャード上で) 結合を実行できます。シャード・キーとして使用される 2 つのフィールド間の等値条件が含まれていなければ、結合をこのようにコシャードすることはできません。同様に、それぞれのテーブルのシャード・キーに、フィールド値の等値性を比較できるタイプの同じフィールド番号が同じ順序で存在する限り、複数フィールドの UDSK を使用して、コシャード結合を有効にできます。
多くのケースで有効なその他のアプローチでは、SASK を使用して 1 つのテーブルを作成し、最初のテーブルと共にコシャードされることを示す coshard with キーワード、および最初のテーブルのシステムが割り当てた RowID 値に等しい値を持つシャード・キーを指定することにより、もう 1 つのテーブルを作成します。例えば、以下のように、クエリで ORDER テーブルおよび CUSTOMER テーブルを頻繁に結合しているとします。
SELECT * FROM orders, customers where orders.customer = customers.%ID
この場合、結合の片方のフィールドは RowId を表すため、テーブル CUSTOMER を SASK を使用して次のように作成することから開始します。
CREATE TABLE CUSTOMER (firstname VARCHAR(50) not null, lastname VARCHAR(75) not null,
address VARCHAR(50) not null, city VARCHAR(25) not null, zip INT, shard)
コシャード結合を有効にするには、CUSTOMER テーブルへの参照として customer フィールドが定義されている ORDER テーブルを、そのフィールドで CUSTOMER テーブルとのコシャードを指定することで、シャーディングします。
CREATE TABLE ORDER (date DATE not null, amount DECIMAL(10,2) not null,
customer CUSTOMER not null, shard key (customer) coshard with CUSTOMER)
前に説明した UDSK の例と同様、これにより、ORDER の各行は、RowID 値がその customerid 値と一致する CUSTOMER の行と同じシャード上に配置されます (例えば、customerid=427 であるすべての ORDER 行は、ID=427 の CUSTOMER 行と同じシャード上に配置されます)。このようにして有効になったコシャード結合は、SASK でシャーディングされたテーブルの ID と、そのテーブルと共にコシャードされるテーブルに対して指定されるシャード・キーとの間の等値条件を含む必要があります。
一般には、スキーマで指定した以下のいずれかを使用することで、最も有用なコシャード結合を有効にできます。
-
例に示したとおり、テーブルと coshard with キーワードとの構造的な関係を表す SASK。この例では、ORDER テーブル内の customerid が CUSTOMER テーブル内の RowId への参照となっています。
-
RowID に対応しないため、VEHICLE テーブルおよび CITATION テーブルの等値の vin フィールドと vehiclenumber フィールドの使用で説明したとおりに coshard with を使用してコシャードできない、意味的に重要なフィールドを含む UDSK (多くの結合で使用されますが、表面的またはアドホックな関係を表すフィールドを含む UDSK は、通常あまり役立ちません)。
結合がないクエリやシャード・データとシャード化されていないデータを結合するクエリと同様に、コシャード結合は、シャード数の増加に伴う拡張性に優れているだけでなく、結合されるテーブルの数の増加に伴う拡張性にも優れています。コシャードされていない結合は、シャードや結合されるテーブルの数が適度であれば、優れたパフォーマンスを発揮しますが、それらの数の増加に伴う拡張性にはそれほど優れていません。こうした理由から、例えば、クエリが頻繁に実行されるフィールドのセットのパフォーマンスを向上させるためにインデックスを考慮するのと同様に、この段階でコシャード結合を慎重に検討する必要があります。
シャード・キーを選択する際は、これらの一般的な考慮事項に留意してください。
-
シャード・テーブルのシャード・キーは変更できず、その値を更新することもできません。
-
他の条件がすべて同じであれば、シャード間でのテーブルの行のバランスの取れた分散はパフォーマンスを向上させ、行の分散に使用されるアルゴリズムは、シャード・キーにさまざまな値が大量に含まれるが、主だった異常値はない場合に、最適なバランスを提供します (頻度に関して)。これは既定の RowID が一般にうまく機能するためです。類似した特性を持つ適切な UDSK は効率的であることも多いですが、不適切な UDSK はパフォーマンスの大きな向上が見られない不均衡なデータ分散につながる可能性があります。
-
大きいテーブルがはるかに小さいものに頻繁に結合されるときに、大きいテーブルをシャード化し、小さいテーブルをシャード化されないようにすると、コシャード結合を有効にするより効果的な場合があります。
一意制約の評価
シャード・テーブルに一意制約がある場合 ("InterSystems SQL リファレンス" の “CREATE TABLE” エントリにある "フィールド制約Opens in a new tab" および "複数フィールドでの一意制約Opens in a new tab" を参照)、すべてのシャード間で一意性が保証されます。これは通常、挿入または更新される各行について、すべてのシャード全体で一意性を強制する必要があるため、挿入/更新のパフォーマンスが大幅に低下することを意味します。ただし、シャード・キーが一意キーのフィールドのサブセットである場合は、行が挿入または更新されるシャードでローカルに一意性を強制することにより、すべてのシャード全体で一意性を保証できるため、このようなパフォーマンスへの影響が回避されます。
例えば、指定したキャンパスの OFFICES テーブルに buildingnumber フィールドと officenumber フィールドが含まれているとします。建物番号はキャンパス内で一意であり、オフィス番号は各建物内で一意です。この 2 つを組み合わせて、各従業員のオフィス・アドレスをキャンパス内で一意にする必要があります。したがって、テーブルに対する一意制約を以下のように配置します。
CREATE TABLE OFFICES (countrycode CHAR(3), buildingnumber INT not null, officenumber INT not null,
employee INT not null, CONSTRAINT address UNIQUE (buildingname,officenumber))
ただし、テーブルをシャーディングする予定で、挿入/更新のパフォーマンスへの影響を回避するには、buildingnumber、officenumber、またはその両方をシャード・キーとして使用する必要があります。例えば、buildingnumber に対してシャーディングを行う (shard key (buildingnumber) を上記の文に追加することによる) 場合、各建物のすべての行が同じシャードに配置され、アドレスが “building 10, office 27” である従業員の行を挿入する際に、buildingnumber=10 であるすべての行を含むシャードに、アドレスの一意性をローカルに適用できます。officenumber に対してシャーディングを行う場合、officenumber=27 であるすべての行が同じシャードに配置され、“building 10, office 27” の一意性を、そのシャードにローカルに適用できます。一方、SASK、または UDSK として employee を使用する場合は、buildingnumber と officenumber の任意の組み合わせが任意のシャードに現れる可能性があるため、“building 10, office 27” の一意性をすべてのシャードで適用しなければならず、パフォーマンスに影響が生じます。
このような理由により、次のいずれかが当てはまらない限り、シャード・テーブルでの一意制約の定義は避けることをお勧めします。
Note:
アプリケーション・コードで一意性を強制することにより (あるカウンタに基づくなど)、テーブル内の一意制約の必要性を排除でき、シャード・キーの選択が簡素化されます。
テーブルの作成
クラスタ内の任意のデータ・ノードのクラスタ・ネームスペースで標準の CREATE TABLE 文 ("InterSystems SQL リファレンス" の "CREATE TABLE" を参照) を使用して空のシャード・テーブルを作成します。"シャード・キーの選択" の例で示したように、テーブルを作成する際、2 種類のシャーディング仕様があります。
-
システムが割り当てたシャード・キー (SASK) でシャーディングを行うには、CREATE TABLE 文に shard キーワードを含めます。
-
ユーザ定義のシャード・キー (UDSK) でシャーディングを行うには、shard の後に key とシャーディングするフィールドを指定します (shard key (customerid, purchaseid) など)。
Note:
"CREATE TABLE" リファレンス・ページの "主キーの定義" で説明しているように、テーブルを作成する際に PK_IS_IDKEY オプションを設定すると、テーブルの RowID が主キーになります。このような場合、既定のシャード・キーを使用することは、主キーがシャード・キーとなることを意味します。ただし、主キーをシャード・キーとして使用する場合は、テーブルを作成する前にこの設定の状態を確認しなくても済むように、シャード・キーを明示的に指定することをお勧めします。
ノード 1 または別のデータ・ノードの管理ポータルの [シャード構成] ページ ([システム管理]→[構成]→[システム構成]→[シャード構成]) に移動して、クラスタ・ネームスペースを選択し、[シャードテーブル] タブを選択することによって、名前、所有者、シャード・キーを含む、クラスタ上のすべてのシャード・テーブルのリストを表示できます。データをロードしたテーブルに対し、[詳細] リンクをクリックすると、クラスタ内の各データ・ノードに格納されているテーブルの行数を確認できます。
シャード・テーブルの作成における制約
以下の制約が、シャード・テーブルの作成に適用されます。
-
ALTER TABLE を使用して既存のシャード化されていないテーブルをシャード・テーブルに入れることはできません (ただし、ALTER TABLE を使用してシャード・テーブルを変更することはできます)。
-
SHARD KEY フィールドのデータ型は、数値または文字列でなければなりません。シャード・キー・フィールドについて現在サポートされている照合は、完全一致、SQLString、および SQLUpper のみで、切り捨ては行われません。
-
ROWVERSION フィールドおよび SERIAL (%Counter) フィールド以外のすべてのデータ型がサポートされます。
-
シャード・テーブルに %CLASSPARAMETER VERSIONPROPERTYOpens in a new tab を含めることはできません。
このセクションのトピックの詳細および例は、"InterSystems SQL リファレンス" の "CREATE TABLE" を参照してください。
シャード・クラスを使用したシャード・テーブルの定義
DDL を使用したシャード・テーブルの定義に加え、シャード・クラス・キーワードを使用してクラスをシャード・クラスとして定義することができます。詳細は、"InterSystems SQL の使用法" の “テーブルの定義” の章にある "永続クラスの作成によるシャード・テーブルの定義Opens in a new tab" を参照してください。クラス・コンパイラが拡張され、コンパイル時にシャーディングと互換性のないクラス定義機能 (カスタマイズされたストレージ定義など) の使用に対して警告を発行するようになりました。さらに成熟した作業負荷メカニズムや一部の互換性のない機能のサポートは、InterSystems IRIS の今後のバージョンで導入される予定です。