12cR2.4.4.6での変更点
Oracle NoSQL Database 12cR2.4.4.6で次の変更が行われました。
トピック
新機能
-
JSONデータの索引付けが追加されました。
現行のリリースでは、Oracle NoSQLのSQLで型指定されたJSON索引がサポートされます。名前が示すように、このような索引により、索引付け対象のJSONデータに、型関連の制約が適用されます。索引によって課される制約に違反するデータを持つ行が関連表に含まれている場合、型指定されたJSON索引の作成は失敗します。同様に、1つ以上の既存のJSON索引によって課される制約に新規行が準拠しない場合、挿入/更新操作は拒否されます。ただし、型制約が満たされているかぎり、型指定されたJSON索引は、コンテンツの評価方法とコンテンツの問合せでの使用方法の両方において、強力に型指定されたデータの索引と非常によく似ています。
構文的には、JSON索引と非JSON索引の違いは、JSONフィールドを索引付けする索引パスごとにCREATE INDEX文で型を指定する必要があるという点のみです。型は、JSONアトミック型(数値型、文字列型またはブール型)のいずれかである必要があります。このような型宣言は、索引パス式によって返されるアイテムが表の行で評価されるときに、指定された型、SQL NULLまたはJSON nullである必要があることを意味します。また、索引付きパスがデータに存在しなくてもかまいません。この場合、パス式は空の結果を返し、特殊な(内部)値EMPTYが索引に配置されます。
非JSON索引と同様に、JSON索引は「単純」または「マルチキー」である場合があります。後者は、配列のすべての要素またはJSONオブジェクトのすべてのエントリを索引付けするために使用します。次に、各種索引の例を示します。これらの例では、次の表を使用します。
create table foo (id integer, firstName string, lastName string, address json, primary key(id));
前述の表のサンプル行は、次のようになります(JSON形式で表示)。
{ "id":0, "firstName" : "John", "lastName" : "Doe", "address": { "street" : "somewhere", "city": "San Francisco", "state" : "CA", "phones" : [ { "area":408, "number":5039567, "kind":"work" }, { "area":415, "number":2854026, "kind":"work" }, { "area":null, "number":8390129, "kind":"home" }, ] } } create index idx1 on foo (address.state as string, address.city as string)
前述の索引では、
address.state
パスとaddress.city
パスの両方が文字列、NULL、JSON nullまたはEMPTYを返します(SQL NULLは、最上位レベルのaddress
列がNULLである場合にのみ返されます)。また、パスにはマルチキー・ステップ([]、.value()または.key())が含まれていないため、これらは最大で1つのアイテムを返す必要があります。これは、パス(address
、address.state
またはaddress.city)
内のどのフィールドも配列でないことを意味します。create index idx2 on foo (address.state as string, address.phones[].area as integer, address.phones[].kind as string)
前述の索引では、パス
address.phones[].area
とaddress.phones[].kind
に[]ステップが含まれるため、これらのパスはマルチキーです。これは、address.phones
が配列になることが想定される(および、この2つのパスの他のフィールドは配列になることができない)ことを意味します。ただし、address.phones
は単一のJSONオブジェクトでも、アトミック値でも構いません。一般に、索引パスはDML問合せのパス式と同じように評価されます。したがって、address.phones
がareaおよびkindフィールドを持つ単一オブジェクトである場合、これらのフィールドの値は索引付けされます。address.phones
がアトミック値である場合、パス式の結果は空で、EMPTYが索引に配置されます。[#25509] -
EMPTY値は、式から空の結果が返されるケースを表すために内部で使用されます。アプリケーションは通常、EMPTY値を処理する必要はありません。唯一の例外はIndexKeyインスタンスです。TableIteratorを使用して索引をスキャンし、索引キーを返す場合、返されたIndexKeyインスタンスにEMPTY値が表示される場合があります。
FieldValue.isEMPTY()
メソッドを使用すると、IndexKeyフィールドの値がEMPTYであるかどうかをチェックできます。アプリケーションは、IndexKey.putEMPTY()
メソッドを使用して、1つ以上のフィールドにEMPTY値を含むエントリの索引を検索することもできます。[#25509] -
NUMBERデータ型が追加されました。NUMBERデータ型は、
java.math.BigDecimal
値を表します。これは、任意のサイズおよび精度の数値を処理できる汎用数値型として使用できます。型NUMBERのフィールドは、主キーまたは索引キーのフィールドとして使用できます。数値を処理する問合せ式はすべて、NUMBER値も処理するために拡張されました。[#25447] -
NoSQLのSQLに演算子IS NULLおよびIS NOT NULLが追加されました。標準SQLの場合と同様、演算子は、式の結果がSQL NULLであるか(またはそうでないか)をテストします。演算子は「sargable」です。つまり、該当する索引が存在する場合に索引キーに対する条件として評価できます。[#25809]
-
4.2.では、NULL値の索引付けが導入されました。ただし、4.2と4.3では、NULLが「欠落」値、より正確には、行の索引パスの評価で空の結果(EMPTY)が返される場合の索引付けにも使用されていました。現在のリリースでは、NULLおよびEMPTYは個別に索引付けされます。これは、IS (NOT) NULL演算子をsargableにするために必要です。次の例で理由を確認してみます。
create table foo (id integer, map MAP(RECORD(f1 integer, f2 integer))) create index idx on foo (map.somekey.f1) select * from foo where map.somekey.f1 IS NULL Row R1: { "id" : 1, "map" : null } Row R2 : { "id : 2, "map" : { } } Row R3 : { "id : 3, "map" : { "somekey" : {"f2" : 10} } }
行R1およびR3は問合せの結果セット内にありますが、R2はそうではありません(R2の場合、map.key.f1がEMPTYを返すため)。
4.2では、索引には前述のすべての行に対してNULLが含まれます。現在のリリースでは、R1およびR3の場合はNULL、R2の場合はEMPTYが含まれます。したがって、現在のリリースでは、索引を使用して問合せを最適化できます。[#25509]
-
引用符付き文字列を索引パスのステップとして許可します。これは、マップの特定のエントリのキーが単純な識別子ではない場合に、そのエントリに索引を付けることを可能にするために必要です。次に例を示します。
CREATE TABLE Foo(id INTEGER, map MAP(INTEGER)), primary key(id)) create index idx on Foo (map."@abc")
このリリースより前では、引用符で囲まれた文字列はステップとして許可されていなかったため、前述の索引は作成できませんでした。
@abc
が('@' charが原因で)有効な識別子ではないため、パスmap.@abc
を使用しようとすると失敗しました。[#25854], [#25958], [#25963], [#25974] -
問合せ内にある文字列リテラルに出現するエスケープ・シーケンスは、問合せの解析時に対応するUnicode文字に変換(インライン化)されます。これが必要なのは、JSONデータ・モデルで同じ変換が適用されるためです。そのため、たとえば、JSONテキストがOracle NoSQLにロードされると、JSONテキスト内のエスケープ・シーケンスはすべてインライン化されます。その結果、問合せに表示される文字列リテラルは、格納されたデータで使用されるものと内部的に同じ「形式」である必要があります。[#25767]
-
同じシャード内のあるレプリケーション・ノードから別のレプリケーション・ノードへのネットワーク・リストアを実行するために、新しいプラン
plan network-restore
が追加されました。このプランを使用すると、セカンダリ・ノードからプライマリ・レプリケーション・ノードにデータをリストアできます。たとえば、シャードの定数が失われ、マスターを使用できない場合に、別のノードからレプリカをリストアできます。また、このプランを使用して、破損したデータがあるレプリケーション・ノードをリストアすることもできます。[#25834] -
このリリース以降、ストレージ・ノード、管理、レプリケーション・ノードおよびセキュリティの構成ファイルは、デフォルトでは所有者の読取り専用に設定されます。たとえば、ルート・ディレクトリのconfig.xmlおよびセキュリティ構成ディレクトリのsecurity.xmlです。[#25835]
-
Oracle NoSQL Databaseでは、ユーザーのパスワードはセキュリティ・メタデータ・データベースでハッシュした後に格納し、ハッシュ・アルゴリズムは
PBKDF2WithHmacSHA1
を使用していました。このリリース以降、より強力なアルゴリズムPBKDF2WithHmacSHA256
に置き換えられています。この変更では既存のユーザーのパスワードのハッシュは更新されないことに注意してください。アップグレード後に新しいアルゴリズムを使用するように、ユーザーのパスワードを更新することをお薦めします。[#26014] -
表形式でのdescribe tableおよびdescribe index出力をサポートします。[#25720]
-
describe tableおよびdescribe index出力を表形式で表示します。[#25720]
-
プランの進行状況はJMXを介して確認できます。シリアル・プランとパラレル・プランの両方についてプランのステータスとその関連タスクをレポートするためにJMX通知が生成されます。これは次のサンプルに示すように、一般タスクと、パーティションの移行などの拡張度操作に関連付けられたタスクの両方についてレポートします。[#25200]
{ "planId": 17, "planName": "Deploy Topo (17)", "reportTime": 1483445963460, "state": "RUNNING", "attemptNumber": 1, "migratePartition_Total": 150, "generalTask_Total": 14, "migratePartition_Successful": 15, "generalTask_Successful": 13, "migratePartition_Running": 135, "generalTask_NotStarted": 1 }
バグとパフォーマンスの修正
-
以前のリリースでは、WHERE句がない問合せで「索引を網羅する」最適化は考慮されていませんでした。これは、現在のリリースで修正されました。その結果、
select id1 from foo
(id1は表fooの主キー列)などの問合せは、すべての表の行を取得するのではなく、表の主キーに対するキーのみをスキャンして評価されます。[#25509] -
order-by句に主キー列が含まれるorder-by問合せのバグが修正されました。ソートは索引ベースであるため、索引付きフィールドはすべて、order-by句で主キー列の前に指定する必要があります。そうしない場合、問合せは拒否されます。この制限は以前のリリースでは適用されていなかったため、ソート結果に誤りが生じることがありました。[#25509]
-
マップに対する問合せと索引の特定の組合せにより、問合せ実行時にエラーが発生していました。最も重要なケースは、索引がマップの3つ以上の特定のキーに索引を付け、索引フィールドのみを使用した索引スキャン中に問合せがその索引によって1つ以上の式を評価する場合です(全表の行を取得する必要はありません)。そのようなケースを示す例を次に示します。
CREATE TABLE Foo( id INTEGER, g LONG, rec RECORD(a INTEGER, b ARRAY(INTEGER), c MAP(RECORD(ca INTEGER, cb INTEGER, cc INTEGER, cd INTEGER))), primary key(id)) create index idx on Foo (rec.c.key1.ca, rec.c.key2.ca, rec.c.key3.cb)
問合せ:
select id from Foo f where f.rec.c.key1.ca >= 3 and f.rec.c.key2.ca = 20
この問合せでは、WHERE句の最初の述語が索引スキャンの開始条件として使用されています。この場合、問題は発生しません。問題の原因は、「フィルタ処理」述語として使用されている2番目の述語です。これは、現在の索引エントリの2番目のフィールド(rec.c.key2.ca)を使用して、索引のスキャン中に評価されています。さらに、索引では、3つの特定のマップ・キー(key1、key2およびkey3)が索引付けされています。パスrec.c.key3.cbが索引定義の一部ではなかった場合、バグは表示されませんでした。[#25822]
-
マップ・キーの大/小文字が区別されるという事実は、問合せプロセッサが特定のマップ・キーで索引の使用を検討するときに考慮されませんでした。このため、問合せでは間違った索引が使用されることがありました。次に例を示します。
CREATE TABLE Foo (id INTEGER, map MAP(INTEGER), primary key(id)) CREATE INDEX idx ON Foo (map.SomeKey) select id from Foo f where f.map.somekey = 3
前述の問合せは索引を使用しています。しかし、マップ・キーSomeKeyとsomekeyが異なるため、これは間違いになります。
INDEX CREATE文の実行時に、同じフィールドを持つ索引がすでに存在するかどうかを確認するためのチェックが行われた際も、マップ・キーの大/小文字区別は考慮されていませんでした。[#25959]
-
場合によっては、重複した問合せ結果の除去は実行されませんでした。特に、問合せでマルチキー索引を使用しており、その索引に述語がプッシュされていない場合は、重複削除は行われていませんでした。述語がtiにプッシュされていなくても、索引がソートに使用されている場合(order-by問合せ)、またはその使用が索引ヒントによって強制されている場合は、索引が問合せによって使用されます。[#26008]
-
比較演算子の複数のバグが修正されました。これらのバグは、問合せによって誤った結果が返されたりNPEが発生したりする原因となる場合があります。ただし、これらのバグが表示されることはめったにありません。[#25832]
-
長整数または倍精度リテラルがそれぞれ整数型または浮動小数点型の式と比較されるときに、長整数または倍精度リテラルが整数または浮動小数点の範囲外にある場合、バグが発生する可能性があります。また、式は1つ以上のNULL、空の結果、または複数のアイテムを返す必要があり、演算子は値比較演算子です。
-
長整数または倍精度リテラルがそれぞれ整数型または浮動小数点型の式と!=または!=anyを介して比較されるときに、長整数または倍精度リテラルが整数または浮動小数点の範囲外にある場合、バグが発生する可能性があります。
-
JSON nullが、型にJSON nullを含まない式と比較され、(a)式がSQL NULLを返すか、(b)式がEMPTY (空のシーケンス)を返し、比較演算子が!=anyである場合、バグが発生します。
-
複数値のパス式がconstと比較され、パス式が索引の複数キー・パスと一致し、問合せでその索引が使用され、比較述語が索引スキャンの開始/停止条件に変換される場合、バグが発生します。たとえば、
t.array[] = 5
で、arrayが型array(integer)を持つ表tの列である場合です。通常、arrayに複数の要素が含まれる行がある場合、この述語が原因でエラーが発生します。ただし、arrayに索引も存在し、述語がその索引にプッシュされる場合、エラーが解消される可能性があり、問合せで結果が返されます。
-
-
入力式がEMPTY型の場合に配列フィルタ式で発生するコンパイル・バグが修正されました。たとえば、問合せ
select f.info.children.keys().age[$element > 4] from foo f
ではEmptyStackExceptionが発生します。SELECT句に出現するパス式では、keys()ステップによって常に一連の文字列が返されます。その結果、これらの文字列に対する.ageステップは常に空の結果になります。したがって、コンパイラは、型EMPTYをf.info.children.keys().age
式に割り当てます。これが、後続の配列-フィルタ・ステップ([$element > 4])で正しく処理されませんでした。[#25877] -
JSONテキストを解析して、厳密に型指定された表スキーマにマップするコードが、無効なJSONドキュメントを正しく処理していませんでした。これはこのリリースで修正されています。[#25842]
-
以前のリリースでは、toByteArray (および関連する)メソッドによって返される値の動作が保証されていないことがドキュメントに明記されました。現在または以前のリリースで作成されたバイト配列値は、現在またはそれ以降のリリースのバイト配列値を受け入れる関連メソッドに渡すことができますが、以降のリリースで作成される値は、以前のリリースのメソッドに渡されても互換性があるかは保証されません。
影響を受けるメソッドは次のとおりです。
-
Consistency.toByteArray
およびfromByteArray
-
Durability.toByteArray
およびfromByteArray
-
ExecutionFuture.toByteArray
およびKVStore.getFuture
-
Key.toByteArray
およびfromByteArray
-
KeyRange.toByteArray
およびfromByteArray
-
Value.toByteArray
およびfromByteArray
-
Version.toByteArray
およびfromByteArray
-
-
Java SE Development Kit 8, Update 121 (JDK 8u121)を使用したセキュアなストアの実行中に発生するRMIレジストリ・フィルタの問題が修正されました。これは、RMIの優れた制約チェックと呼ばれるJavaの新機能が原因でした。この修正では、セキュアなストアと非セキュアなストアの両方でストレージ・ノード・エージェントを起動するとき、パターン
oracle.kv.**;java.lang.Enum
がない場合に、このパターンがRMIレジストリ・フィルタsun.rmi.registry.registryFilter
に自動的に追加されるようになりました。[#25923] -
ユーザー指定の暗号スイートが構成されていない場合に、GCM暗号化アルゴリズム・モードを使用するスイートを優先するようSSL暗号スイートのプリファレンス順序が変更されました。Oracleの実験的なパフォーマンス・テストでは、特にハードウェアでセキュアなランダム性のソースが限定されている場合に、GCMを使用したスイートの方がパフォーマンスに優れていることが確認されています。[#25949]
-
クローズしたストア・ハンドルに対する問合せを発行する際のエラー・メッセージがよりわかりやすくなるよう変更されました。[#25883]
-
セカンダリ・ゾーンのデータが既存のアライブ・プライマリ・ゾーンよりも新しい場合にフェイルオーバー操作で障害が発生するという問題が修正されました。修正により、フェイルオーバー後にデータ損失があるかどうかを検出する潜在的データ損失検証が追加されました。セカンダリ・ゾーンのデータを保持するために、ユーザーはまず、主要セカンダリ・ノードからプライマリ・ノードへのネットワーク・リストアを実行する必要があります。そうでない場合は、強制を指定してフェイルオーバー・プランを再度実行します。[#24772]
-
JSON文字列の0.0を浮動小数点値として解析できなかった問題が修正されました。[#25983]
-
EEバージョンでセキュリティ保護されたKVLiteを再起動するとIllegalStateException「Unable to access the configured wallet store」で失敗する問題が修正されました。これは、ウォレット・ファイルを同時にオープンしようとしたことが原因です。[#25990]
-
Elasticsearchライブラリがv2.4.4.にアップグレードされました。[#25943]
-
管理ノードの再起動が失敗してIllegalCommandExceptionが発生する問題が修正されました。管理ノードが再起動してマスターになると、フェイルオーバー時に実行されていたすべてのプランが再起動されます。この修正より前は、プランの再起動中にIllegalCommandExceptionが発生すると、管理ノードの再起動に失敗することがありました。[#26022]
-
一括put APIで、単一ストリームによって提供された重複キーを持つエントリが、キーが実際にストア内で見つかる前に存在するとマークされる問題が修正されました。[#25903]
ユーティリティの変更点
-
次のタイプのSN JMX通知JSON形式データで、フィールド名をdatetimeからreportTimeに変更します。[#25979]
-
oracle.kv.repnode.opmetric
-
oracle.kv.repnode.envmetric
-
oracle.kv.repnode.replicationstate
-
oracle.kv.repnode.status
-
oracle.kv.plan.status
-
-
名前付きの表に行を配置するためのputコマンドをSQLシェルに追加しました:
put -table <name> [-json <string> | -file <file> [JSON | CSV]]