CREATE TABLE文

表は、ユーザー・データを保持するための基本構造です。create table文を使用して、Oracle NoSQL Databaseで新しい表を作成します。

構文

create_table_statement ::= 
   CREATE TABLE [IF NOT EXISTS] table_name [comment] 
   "(" table_definition ")" [ttl_definition]

table_name ::= [namespace_name ":"] name_path
name_path ::= field_name ("." field_name)*
field_name ::= id | DSTRING

table_definition ::= 
   (column_definition | key_definition) 
   ("," (column_definition | key_definition))*
column_definition ::= 
   id type_definition 
   [default_definition | identity_definition | 
uuid_definition] 
   [comment]
key_definition ::= 
   PRIMARY KEY 
   "(" [shard_key_definition [","]] [id_list_with_size] ")" 
   [ttl_definition]
id_list_with_size ::= id_with_size ("," id_with_size)*
id_with_size ::= id [storage_size]
storage_size ::= "(" INT_CONSTANT ")"
shard_key_definition ::= SHARD "(" id_list_with_size ")"
ttl_definition ::= USING TTL INT_CONSTANT (HOURS | DAYS)

セマンティクス

table_name

表名は、オプションのnamespace_nameおよびlocal_nameとして指定されます。ローカル名はname_pathです。これは、子表の場合はドット区切りidのリストで構成されるためです。子表については、表階層の項で説明します。namespace_nameを含むtable_nameは、修飾表名と呼ばれます。SQL文(DDLまたはDML)がローカル名のみで表を参照する場合、ローカル名は特定の名前空間名を持つ修飾名に内部的に解決されます。ネームスペース管理の章を参照してください。

IF NOT EXISTS

これはオプションの句です。この句が指定されており、同じ修飾名の表が存在する(または作成中の)場合、その既存の表の構造が文の構造と同じであれば、エラーは生成されません。それ以外のすべての場合で、同じ修飾名の表が存在する場合、create table文は表が存在することを示すエラーを生成します。

ttl_definition

存続時間(TTL)値は、行の有効期限を計算するために使用されます。期限切れになった行は問合せ結果に含まれず、最終的にOracle NoSQL Databaseによって表から自動的に削除されます。表の作成時にTTL値を指定すると、この表に挿入されるすべての行のデフォルトのTTLとして適用されます。ただし、表挿入APIを使用してTTL値を指定すると、表レベルのTTLをオーバーライドできます。

行の有効期限は、TTL値を現在のタイムスタンプに加えて算出されます。具体的には、N時間/日のTTL値では、有効期限は現在の時刻(UTC)にN時間/日を加えたもので、次の時間/日に切り上げられます。たとえば、現在のタイムスタンプが2020-06-23T10:01:36.096でTTLが4日の場合、有効期限は2020-06-28T00:00:00.000になります。ゼロを特別な値として使用して、行が期限切れにならないことを示すことができます。CREATE TABLE文にTTLの指定がない場合、デフォルトの表TTLはゼロです。

TTL値が定義されているMR表の場合、他のリージョンにレプリケートされた行は、行が書き込まれたときの有効期限を保持します。これは、デフォルトの表レベルTTL値またはアプリケーションで設定された行レベルのオーバーライドのいずれかです。したがって、この行は、レプリケートされた時期に関係なく、すべてのリージョンで同時に期限切れになります。ただし、いずれかのリージョンで行が更新され、いずれかのリモート・リージョンにレプリケートされる前であっても、ローカル・リージョンで期限切れになる場合、この行は、そのリモート・リージョンでレプリケートおよびコミットされるとすぐに期限切れになります。

table_definition

文のtable_definition部分には、少なくとも1つのフィールド定義と、1つの主キー定義が含まれている必要があります(構文では複数のkey_definitionsを使用できますが、問合せプロセッサにより1つのkey_definitionルールが適用されます。構文ではこの用法で、キー定義をフィールド定義のどこにでも表示できます)。

column_definition

列定義の構文は、レコード・タイプのフィールドを定義するfield_definition構文規則に似ています。データ型の定義の項を参照してください。これは、列の名前、データ型、列がNULL値可能かどうか、オプションのデフォルト値、または列がIDENTITY列かどうか、およびオプションのコメントを指定します。表管理の項で説明したように、表はレコードのコンテナであり、table_definitionsは、リストされたcolumn_definitionsによってフィールドが定義されるレコード・タイプ(表スキーマ)の暗黙的な定義として機能します。ただし、DDL文でtype_definition構文規則が使用される場合、使用できるワイルドカードのタイプはJSON型のみです。そのため、たとえば、JSON型の列を持つ表は作成できますが、ANY型の列を持つ表は作成できません。

identity_definition

identity_definitionは、アイデンティティ列の名前を指定します。表ごとに1つのアイデンティティ列のみが許可されます。IDENTITY列の使用の項を参照してください。

uuid_definition

uuid_definitionは、列の型をUUID型として宣言します。UUIDデータ型の使用を参照してください。

key_definition

主キー仕様の構文(key_definition)は、表の主キー列をフィールド名の順序付きリストとして指定します。列名はfield_definitionsに表示される列名の中に含まれている必要があり、関連付けられている型は、数値型、文字列、列挙またはタイムスタンプのいずれかである必要があります。主キーの通常の定義が適用されます。同じ表の2つの行が、そのすべての主キー列に同じ値を持つことはできません。

shard_key_definition

key_definitionでは、表のシャード・キー列に加えて、最初のN個の主キー列が指定されます。0 < N <= Mで、Mは主キー列の数です。shardキーの指定はオプションです。デフォルトでは、ルート表(親のない表)の場合、シャード・キーは主キー全体です。意味的には、シャード・キーは、Oracle NoSQL Databaseストアを構成する複数のサーバーとプロセスに表の行を分散するために使用されます。簡単に言うと、同じシャード・キーを持つ2つの行、つまり、シャード・キー列の同じ値は、常に同じサーバーに配置され、同じプロセスで管理されます。Oracle NoSQL Databaseでのデータの分散の詳細は、主キーとシャード・キーの設計の項を参照してください。

storage_size

INTEGER型の主キー・フィールドの追加プロパティは、記憶域サイズです。これは1から5の整数として指定されます(構文では任意の整数が許可されますが、問合せプロセッサにより制限が適用されます)。記憶域サイズは、関連付けられた主キー列の値をシリアル化された形式で格納するために使用できる最大バイト数を指定します。値を指定されたバイト数以下にシリアル化できない場合、エラーがスローされます。INTEGER (およびLONG)主キー値を格納するために内部エンコーディングが使用されるため、そのような値は文字列としてソートできます(主キー値は常に主Bツリー索引のキーとして格納されるため)。次の表に、バイト・サイズごとに格納できる正の値の範囲を示します(負の値も範囲は同じです)。ユーザーは、キー値が選択した記憶域サイズに関連付けられた範囲の上限以下になることがわかっている場合、5未満の記憶域サイズを指定して記憶域スペースを節約できます。

comment

コメントは表レベルで含まれ、解釈されないテキストとして表のメタデータの一部になります。コメントは、describe文の出力に表示されます。

例5-1 Create Table

次のcreate table文は、ユーザーに関する情報を保持するusers表を定義します。

CREATE TABLE users (
    id INTEGER,
    firstName STRING,
    lastName STRING,
    otherNames ARRAY(RECORD(first STRING, last STRING)),
    age INTEGER,
    income INTEGER,
    address JSON,
    connections ARRAY(INTEGER),
    expenses MAP(INTEGER),
PRIMARY KEY (id)
);

上で定義されているUsers表の行は、ユーザーに関する情報を表します。そのような各ユーザーの接続フィールドは、このユーザーが接続している他のユーザーのidを含む配列です。配列のIdは、接続の強さのなんらかの測定でソートされることを前提としています。expenses列は、経費カテゴリ(housing、clothes、booksなど)を関連カテゴリで使用された金額にマッピングするマップです。カテゴリのセットは事前にわからない場合があり、ユーザーごとに大きく異なる場合や、ユーザーごとにカテゴリを追加または削除して頻繁に更新する必要がある場合があります。その結果、レコード・タイプのかわりに費用のマップ・タイプを使用することが適切な選択となります。最後に、address列のタイプはJSONです。addressの一般的な値は、次のようなJSONドキュメントを表すマップになります。

{
    "street" : "Pacific Ave",
    "number" : 101,
    "city"   : "Santa Cruz",
    "state"  : "CA",
    "zip"    : 95008,
    "phones" : [
            { "area" : 408, "number" : 4538955, "kind" : "work" },
            { "area" : 831, "number" : 7533341, "kind" : "home" }
    ]
}

ただし、他の有効なJSON値が格納される場合があります。たとえば、一部の住所には、追加のフィールドがある場合や、フィールドがない場合、またはフィールドのスペルが異なる場合があります。または、phonesフィールドがJSONオブジェクトの配列ではなく、単一のそのようなオブジェクトである場合があります。または、住所全体が1つの文字列、数値またはJNULLの場合があります。