表の定義
Oracle NoSQL Databaseクライアントがストア内の表の読取りまたは書込みを実行する前に、まず表を作成する必要があります。実行方法はいくつかありますが、このドキュメントでは表DDL文を使用する方法を中心に説明します。これらの文は、管理コマンドライン・インタフェース(CLI)のexecute
コマンドまたはSQL CLIを使用してストアに直接送信できます。ただし、DDL文をストアにプログラムで送信する方法をお薦めします。この項では、直接的な方法とプログラムによる方法の両方について説明します。
表の定義に使用するDDL言語については、表データ定義言語概要で説明しています。この項では、この言語の使用方法を簡単に説明します。
初歩的な例として、myTable
という名前の表を作成し、次の4つの列があるとします: item
、description
、count
およびpercentage
。表を作成するには、SQL CLIから次の文を使用します。
sql-> CREATE TABLE myTable (
item STRING,
description STRING,
count INTEGER,
percentage DOUBLE,
PRIMARY KEY (item) // Every table must have a primary key
);
Statement completed successfully
注意:
主キーは、まだ説明していない概念です。主キーの機能および使用方法の詳細は、主キーとシャード・キーの設計を参照してください。ここでは、前述の例で示されているように、作成するすべての表に主キーが存在することを確認します。
プログラムによるDDL文の実行
表定義をストアにプログラムで追加するには、Store.execute()
またはStore.execute_sync()
のメソッドを使用します。(後者のメソッドは文を同期的に実行します。)
次に例を示します。
...
### Store handle configuration and open skipped for brevity
...
try:
ddl = """CREATE TABLE myTable (
id STRING,
description STRING,
count INTEGER,
percentage FLOAT,
PRIMARY KEY (item)
)"""
store.execute_sync(ddl)
logging.debug("Table creation succeeded")
except IllegalArgumentException, iae:
logging.error("DDL failed.")
logging.error(iae.message)
管理CLIからのDDL文の実行
管理CLIのexecute
コマンドを使用してDDL文を実行できます。これはDDL文を同期的に実行します。次に例を示します。
kv-> execute "CREATE TABLE myTable (
> item STRING,
> description STRING,
> count INTEGER,
> percentage DOUBLE,
> PRIMARY KEY (item))"
Statement completed successfully
kv->
サポートされている表データ型
Oracle NoSQL Database表の列ごとにスキーマを指定します。このスキーマはオブジェクトとしてハンドリングされるプリミティブ・データ型または複合データ型にできます。
データ型 | 説明 |
---|---|
配列 | すべてが同じ型の値の配列。 |
バイナリ | 事前決定されている固定サイズのないバイト配列として実装されています。 |
ブール | |
倍精度 | |
列挙 | 文字列の配列として表される列挙。 |
固定バイナリ | 事前決定されている固定サイズのないバイト配列として実装されています。 |
浮動小数 | |
整数 | |
Json | 任意の有効なJSONデータ。 |
ロング | |
数値 | 任意の型の数値または任意の値や精度を処理できる数値型。 |
マップ | すべてのエントリが1つの型に制約される、順序のないマップ型。 |
レコード | 次の項を参照してください。 |
文字列 | |
タイムスタンプ | 日付およびオプションで時間値をカプセル化する絶対タイムスタンプ。 |
Pythonでは、サポートされるデータ型は次のように処理されます。
Oracle NoSQL Databaseのデータ型 | Pythonのデータ型 |
---|---|
配列 |
Pythonのarray。配列の使用を参照してください。 |
バイナリ |
Base64でエンコードされたバッファ。バイナリの使用を参照してください。 |
ブール |
Pythonのboolean |
倍精度 |
Pythonのlong |
列挙 |
Pythonのstring。列挙の使用を参照してください。 |
固定バイナリ |
Base64でエンコードされたバッファ。固定バイナリの使用を参照してください。 |
浮動小数 |
Pythonのfloat |
整数 |
Pythonのint |
ロング |
Pythonのlong |
マップ |
Pythonのdictionary。マップの使用を参照してください。 |
レコード |
Pythonのdictionary。埋込みレコードの使用を参照してください。 |
文字列 |
Pythonのstring |
レコード・フィールド
「子表の定義」で説明したように、下位情報(連絡先データベースの住所、在庫システムのベンダー連絡先情報など)を保持する子表を作成できます。その際に、子表に無限の数の行を作成し、子表の行のフィールドに索引を付けることができます。
注意:
簡単なケースでも子表を使用することにデメリットはありません。レコード・フィールドを使用する際に前提となるのは、管理する既知の固定数レコードがあるということです(レコードを配列として編成しない場合)。たとえば、連絡先データベースでは、子表を使用すると、ユーザーごとに無制限の数の住所を関連付けることができます。子表ではなくレコードを使用すると、サポートされている住所(自宅、勤務先など)のレコード・フィールドを作成することで、固定数の住所を関連付けることができます。
次に例を示します。
CREATE TABLE myContactsTable (
uid STRING,
surname STRING,
familiarName STRING,
homePhone STRING,
workPhone STRING,
homeAddress RECORD (street STRING, city STRING, state STRING,
zip INTEGER),
workAddress RECORD (street STRING, city STRING, state STRING,
zip INTEGER),
PRIMARY KEY(uid))
レコード・フィールドの配列を作成することもできます。これにより、フィールドごとに無制限の数の住所フィールドを作成できます。ただし、一般的にこの例では子表を使用してください。
CREATE TABLE myContactsTable (
uid STRING,
surname STRING,
familiarName STRING,
homePhone STRING,
workPhone STRING,
addresses ARRAY(RECORD (street STRING, city STRING, state STRING,
zip INTEGER))),
PRIMARY KEY(uid))
IDENTITY列を使用した表の定義
行を追加するたびに値が自動的に増加するようにIDENTITY列を作成できます。
IDENTITY列をCREATE TABLE name
DDL文の一部として作成するか、ALTER TABLE name
DDL文を使用して既存の表にIDENTITY列を追加します。
1つの表に存在できるIDENTITY列は1つのみです。データ型は、INTEGER
、LONG
またはNUMBER
である必要があります。
すべてのIDENTITY列は表の一部であり、独立オブジェクトとして存在できません。IDENTITY列の追加の詳細は、Javaダイレクト・ドライバ開発者ガイドのIDENTITY列の変更または削除を参照してください。
IDENTITY列には関連付けられたシーケンス・ジェネレータ(SG)が必要です。SGは、IDENTITY列の現在の値、次の値および値の合計数を追跡するための表のマネージャです。SGには、その動作を定義する複数の属性(IDENTITY列の開始値や、キャッシュに格納される値の数など)があります。オプションで、IDENTITY列を作成する際に一部のSGの属性を定義したり、すべてのデフォルト値を使用できます。シーケンス・ジェネレータの属性の詳細は、Javaダイレクト・ドライバ開発者ガイドのシーケンス・ジェネレータの属性を参照してください。
注意:
表内でIDENTITY列を使用しても、一意性は強制的には適用されません。アプリケーションでIDENTITY列のすべての行に一意の値が必要な場合は、その列をGENERATED ALWAYS AS IDENTITYとして作成して、SGのCYCLE属性の使用を許可しない必要があります。複数のクライアントが、このように一意の値について定義されたIDENTITY列を持つ表にアクセスする場合、各クライアントには、連続した値セットがそのSGキャッシュに割り当てられます。これらのセットは、他のクライアント・セットと重複しません。たとえば、Client1
には値0001 – 1000
、Client2
には1001 – 2000
、などと割り当てられます。したがって、それぞれのクライアントが表に行を追加すると、IDENTITY値は0001、1001、0002、1002、1003のようになります(どちらのクライアントも、行を追加するときに独自のキャッシュを使用するため)。IDENTITY列の値は、一意であることが保証されていますが、各クライアントに独自のキャッシュ値のセットがあり、異なる速度で異なる時間に行が追加されるため、必ずしも連続しているとはかぎりません。
ユーザーには、IDENTITY列を持つ表を作成するために表権限が必要です。ユーザー権限の詳細は、セキュリティ・ガイドのKVStore必須権限を参照してください。
IDENTITY列を持つ表の作成
表の作成時にIDENTITY列を作成することも、ALTER TABLE... ADDを使用して、既存の表を変更してIDENTITY列を追加することもできます。いずれの場合も、次に説明するIDENTITY文のいずれかを選択します。この項では、IDENTITY列を含む表の作成について説明します。
GENERATED (ALWAYS | (BY DEFAULT [ON NULL])) AS IDENTITY
[sequence_options,...]
オプションのsequence_options
は、指定できるシーケンス・ジェネレータのすべての属性を参照します。
IDENTITY列の文 | 説明 |
---|---|
GENERATED ALWAYS AS IDENTITY |
常にシーケンス・ジェネレータによってIDENTITY値が指定されます。列の値は指定できません。 |
GENERATED BY DEFAULT AS IDENTITY |
列値を指定しないときは常に、シーケンス・ジェネレータによってIDENTITY値が指定されます。 |
GENERATED BY DEFAULT ON NULL AS IDENTITY |
NULLの列値を指定すると、シーケンス・ジェネレータによって次のIDENTITY値が指定されます。 |
GENERATED ALWAYS AS IDENTITY
を持つ表を作成するには、次のようにします。 sql-> CREATE TABLE IF NOT EXISTS tname1 (
idValue INTEGER GENERATED ALWAYS AS IDENTITY,
acctNumber INTEGER,
name STRING,
PRIMARY KEY (acctNumber));
Statement completed successfully
sql->
この表tname1
では、表に行を追加するたびに、シーケンス・ジェネレータ(SG)によって、そのキャッシュからidvalue
が更新されます。idValue
の値は指定できません。シーケンス・ジェネレータの属性を指定しない場合、SGはデフォルト値を使用します。
sql-> CREATE TABLE IF NOT EXISTS tname2 (
idvalue INTEGER GENERATED BY DEFAULT ON NULL AS IDENTITY,
acctNumber INTEGER,
name STRING,
PRIMARY KEY (acctNumber));
Statement completed successfully
sql->
tname2
では、行を追加するたびに、idvalue
列に値が指定されていない場合、idvalue
列に指定された値がNULLの場合に、SGによってそのキャッシュから次の使用可能な値が挿入されます。
sql-> CREATE TABLE IF NOT EXISTS tname3 (
idvalue INTEGER GENERATED BY DEFAULT AS IDENTITY,
acctNumber INTEGER,
name STRING,
PRIMARY KEY (acctNumber));
Statement completed successfully
sql->
tname3
では、行を追加するたびに、idvalue
列に値が指定されていない場合に、SGによってそのキャッシュから次の使用可能な値が挿入されます。
sg_atts
を作成するには、次のようにします。 sql-> CREATE Table sg_atts (
id INTEGER GENERATED ALWAYS AS IDENTITY
(START WITH 2
INCREMENT BY 2
MAXVALUE 200
NO CYCLE),
name STRING,
PRIMARY KEY (id));
Statement completed successfully
sql->
sg_atts
では、整数のIDENTITYフィールド(id
)が常に生成されることが指定されます。
SGの属性 | 説明 |
---|---|
start with 2 |
順序値は2から開始します。 |
increment by 2 |
行ごとに順序値を2ずつ増加させます。 |
maxvalue 200 |
最大のIDENTITY値を指定します。指定する内容はデフォルト値のmaxvalueをオーバーライドします。これは使用中のIDENTITYデータ型の上限です。IDENTITY列がこの値(200)に達すると、SGはIDENTITY値をそれ以上生成しません。最大値に達し、no cycle属性が使用されています。 |
no cycle |
列がmaxvalue に到達したら、2から、またはいかなる値でも再度開始されることはありません。
|
sg_some_atts
を作成するには、次のように実行します。 sql-> CREATE Table sg_some_atts (
id LONG GENERATED BY DEFAULT AS IDENTITY
(START WITH 1
INCREMENT BY 1
CYCLE
CACHE 200),
account_id INTEGER,
name STRING,
PRIMARY KEY (account_id));
sg_some_atts
表では、id
列GENERATED BY DEFAULT AS IDENTITY
を指定しますが、これは主キーではありません。
SGの属性またはその他の詳細 | 説明 |
---|---|
CYCLE |
CYCLEの指定は、SGによって、指定するMAXVALUE 属性、またはデフォルトのMAXVALUE のいずれかまでのIDENTITY値が指定されることを示します。IDENTITYがMAXVALUE 値に到達すると、SGによって、指定されたMINVALUE から、またはデータ型のデフォルトのMINVALUE から、値が再度開始されます。CYCLEは、迅速なアクセスのためにローカル・キャッシュに格納する値の数のみを指定するCACHE属性とは関連しません。CACHE値は、データ型の最大値を緊密に反映するように設定できますが、クライアント・キャッシュのサイズのため、これはお薦めしません。
|
CACHE 200 |
迅速な取得のために、各クライアントがキャッシュに格納する値の数。IDENTITYがキャッシュ内の最後の数値に達すると、SGはサーバーから別の値のセットを自動的に取得します。 |
START WITH 1 |
SGによって、LONGデータ型の最大値に達するまで、1、2、3などと値が生成されます。 |
INCREMENT BY 1 |
SGによって、新しい行ごとに、それぞれの新しいIDENTITY値が増分されます。 |
シーケンス・ジェネレータのすべての属性の完全なリストは、Javaダイレクト・ドライバ開発者ガイドのシーケンス・ジェネレータの属性を参照してください。
子表の定義
Oracle NoSQL Database表は、親/子階層に編成できます。作成できる子表の数、および子表をネストできる深さに制限はありません。
デフォルトでは親表を取得しても子表は取得されません。同様に、子表を取得しても親表は取得されません。
子表を作成するには、<parentTableName>.<childTableName>の形式を使用して表に名前を付けます。たとえば、myInventory
という名前の簡単な表があるとします。
CREATE TABLE myInventory (
itemCategory STRING,
description STRING,
PRIMARY KEY (itemCategory)
)
次のように、itemDetails
という子表を作成できます。
CREATE TABLE myInventory.itemDetails (
itemSKU STRING,
itemDescription STRING,
price FLOAT,
inventoryCount INTEGER,
PRIMARY KEY (itemSKU)
)
これを実行する場合、子表は親表の主キーを継承することに注意してください。この簡単なケースでは、子表の主キーは実際にはitemCategory
とitemSKU
の2つのフィールドです。これにはいくつかの悪影響があります。その1つは、子表を取得するときに親の主キー・フィールドが取得されるという点です。詳細は、「子表の取得」を参照してください。
複数リージョン表の定義
複数リージョン表、つまりMR表は、様々なリージョンまたはインストールで保管および保守されるグローバル論理表です。これは、複数のリージョンに存在するread-anywhereおよびwrite-anywhere表です。
フランクフルト、ロンドンおよびダブリンの3つのリージョンを持つOracle NoSQL Databaseについて考えてみます。3つのリージョンすべてについて、ユーザー詳細を格納するUsers
という名前の表を作成するには、接続されたグラフ内の各KVStoreにMR表を作成し、その表がまたがるリージョンのリストを指定する必要があります。
たとえば、フランクフルトのリージョンでUsers
表を作成し、リモート・リージョンとしてロンドンとダブリンを指定するには、フランクフルトのリージョンから次のコードを実行する必要があります。
CREATE TABLE Users (
id INTEGER,
firstName STRING,
lastName STRING,
age INTEGER,
primary key (id)
) IN REGIONS London, Dublin;
Users
表を3つすべてのリージョンのMR表として作成するには、ロンドンおよびダブリンのリージョンでもcreate table
文を実行し、そのリモート・リージョンとして他の2つのリージョンを指定する必要があります。
注意:
このプレビュー・リリースのMR表では、TTL機能はサポートされていません。これは、今後のリリースで解除される一時的な制限です。MR表の詳細は、概要ガイドのMR表のライフ・サイクルを参照してください。
表のエボリューション
アプリケーションは長期間使用されるため、多くの場合、表を更新して、新規フィールドを追加したり不要になった既存のフィールドを削除する必要があります。表のエボリューションとは、フィールドを追加または削除したり、デフォルト値などのフィールド・プロパティを変更して、表定義を更新するために使用される用語です。特定の種類の列(IDENTITY列など)を追加して、値を自動的に増やすこともできます。すでにストアに存在する表のみが表のエボリューションの候補となります。
ALTER TABLE
文を使用して、表のエボリューションを実行します。表定義の変更を参照してください。
注意:
フィールドが主キー・フィールドである場合、または索引に参加している場合は、フィールドを削除できません。表のエボリューション中は主キー・フィールドを追加することもできません。
たとえば、次の文は前の項で作成した表を展開します。この例では、APIまたはCLIを使用して、各文を連続してストアに送信します。
ALTER TABLE myInventory.itemDetails (ADD salePrice FLOAT)
ALTER TABLE myInventory.itemDetails (DROP inventoryCount)