表の行の反復使用
TableAPI.tableIterator()
では、非原子的な表の反復を実行できます。 索引を反復するには、このメソッドを使用します。1以外の同時要求サイズを設定した場合、このメソッドは表のパラレル・スキャンを実行します。
TableAPI.tableIterator()
は、行のセット全体を一度に返しません。かわりに、イテレータ内の行のフェッチをバッチ処理し、使用可能な帯域幅を独占することなく、ネットワーク往復を最小限にします。また、このメソッドで返される行はソートされていません。
このメソッドでは1つの原子的操作にならないことに注意してください。取得がバッチ処理されるため、取得操作全体を行ううちに戻りセットが変更されることがあります。その結果、このメソッドを使用する場合、操作の原子性が失われます。
このメソッドでは、表内の行の未ソート走査を行えます。キーを指定しない場合、このメソッドは表のすべての行を反復します。
このメソッドを使用する場合、オプションで次のものを指定できます。
-
MultiRowOptions
クラス・インスタンス。このクラスにより、フィールド範囲、およびこの反復に含める先祖および親表を指定できます。 -
TableIteratorOptions
クラス・インスタンス。このクラスにより、各ネットワーク往復でフェッチするキーの推奨数を指定できます。値0を指定すると、内部的に決められたデフォルトが使用されます。このクラスを使用して、走査順序を指定することもできます(FORWARD
、REVERSE
およびUNORDERED
がサポートされます)。このクラスにより、ストア読取りの実行に使用されるスレッド数を制御することもできます。デフォルトでは、このメソッドは使用可能なプロセッサ数に基づいて同時実行性の度合いを決定します。表の取得に使用するスレッド数を明示的に示すことで、この同時実行性をチューニングできます。詳細は「パラレル・スキャン」を参照してください。
最後に、このクラスを使用して一貫性ポリシーを指定します。詳細は、「一貫性保証」を参照してください。
注意:
TableAPI.tableIterator()
を使用する場合、リソース漏れを防ぐためにイテレータを完了した後にTableIterator.close()
を呼び出すことが重要です。特に長時間実行されるアプリケーションで、とりわけ結果セット全体を繰り返さない場合にこれは大変重要です。
たとえば、次のように設計されている製品に関する情報を格納する表があるとします。
CREATE TABLE myTable (
itemType STRING,
itemCategory STRING,
itemClass STRING,
itemColor STRING,
itemSize STRING,
price FLOAT,
inventoryCount INTEGER,
PRIMARY KEY (SHARD(itemType, itemCategory, itemClass), itemColor,
itemSize)
)
次のようなデータを含む表:
-
行1:
-
itemType: Hats
-
itemCategory: baseball
-
itemClass: longbill
-
itemColor: red
-
itemSize: small
-
price: 12.07
-
inventoryCount: 127
-
-
行2:
-
itemType: Hats
-
itemCategory: baseball
-
itemClass: longbill
-
itemColor: red
-
itemSize: medium
-
price: 13.07
-
inventoryCount: 201
-
-
行3:
-
itemType: Hats
-
itemCategory: baseball
-
itemClass: longbill
-
itemColor: red
-
itemSize: large
-
price: 14.07
-
inventoryCount: 39
-
-
行n:
-
itemType: Coats
-
itemCategory: Casual
-
itemClass: Winter
-
itemColor: red
-
itemSize: large
-
price: 247.99
-
inventoryCount: 9
-
最も簡単な例では、次のようにtableAPI.TableIterator()
を使用して「Hats」に関連するすべての行を取得できます。この単純な例は、TableAPI.multiGet()
メソッドを使用して実行できることに注意してください。完全なシャード・キーがあり、結果セット全体がメモリーにおさまる場合、multiGet()
はtableIterator()
よりも効率よく実行されます。ただし、結果セット全体がメモリーにおさまらない場合、または完全なシャード・キーがない場合、tableIterator()
の方が優れた選択肢となります。tableIterator()
を使用して実行される読取りは非原子的で、更新中のレコードに対して長時間の繰り返しを実行している場合には悪影響がある可能性があります。
package kvstore.basicExample;
...
import oracle.kv.KVStore;
import oracle.kv.table.PrimaryKey;
import oracle.kv.table.Row;
import oracle.kv.table.Table;
import oracle.kv.table.TableAPI;
import oracle.kv.table.TableIterator;
...
// KVStore handle creation is omitted for brevity
...
TableAPI tableH = kvstore.getTableAPI();
// The name you give to getTable() must be identical
// to the name that you gave the table when you created
// the table using the CREATE TABLE DDL statement.
Table myTable = tableH.getTable("myTable");
// Construct the PrimaryKey. In this case, we are
// using a partial primary key.
PrimaryKey key = myTable.createPrimaryKey();
key.put("itemType", "Hats");
// Exception handling is omitted, but in production code
// ConsistencyException, RequestTimeException, and FaultException
// would have to be handled.
TableIterator<Row> iter = tableH.tableIterator(key, null, null);
try {
while (iter.hasNext()) {
Row row = iter.next();
// Examine your row's fields here
}
} finally {
if (iter != null) {
iter.close();
}
}