付録

次のコードでは、Users2表およびUser3表を作成します。

CREATE TABLE Users2 (
    id INTEGER,
    income INTEGER,
    address RECORD(
        street STRING,
        city STRING,
        state STRING,
        phones ARRAY(
            RECORD( 
                area INTEGER, 
                number INTEGER, 
                kind STRING
            )
        )
    ),
    connections ARRAY(INTEGER),
    expenses MAP(INTEGER),
    PRIMARY KEY (id)
);

CREATE TABLE users3 (id INTEGER, info JSON, PRIMARY KEY(id));

次のコードは、Users2表およびUser3表にサンプル行を移入します。

INSERT INTO Users2 VALUES (
    0,
    1000,
    {
        "street" : "somewhere",
        "city": "Boston",
        "state" : "MA",
        "phones" : [ 
            { "area":408, "number":50, "kind":"work" },
            { "area":415, "number":60, "kind":"work" },
            { "area":NULL, "number":52, "kind":"home" }
        ]
    },
    [ 100, 20, 20, 10, 20],
    { "housing" : 1000, "clothes" : 230, "books" : 20 }
);

INSERT INTO Users2 VALUES (
    1,
    NULL,
    {
        "street" : "everywhere",
        "city": "San Fransisco",
        "state" : "CA",
        "phones" : [ 
            { "area":408, "number":50, "kind":"work" },
            { "area":408, "number":60, "kind":"home" }
        ]
    },
    [],
    { "housing" : 1000, "travel" : 300 }
);

INSERT INTO Users2 VALUES (
    2,
    2000,
    {
        "street" : "nowhere",
        "city": "San Jose",
        "state" : "CA",
        "phones" : [ ]
    },
    NULL,
    NULL
);


INSERT INTO users3 VALUES (
    0,
    {
        "income" : 1000,
        "address": {
            "street" : "somewhere",
            "city": "Boston",
            "state" : "MA",
            "phones" : [ 
                { "area":408, "number":50, "kind":"work" },
                { "area":415, "number":60, "kind":"work" },
                { "area":null, "number":52, "kind":"home" }
            ]
        },
        "expenses" : { "housing" : 1000, "clothes" : 230, "books" : 20 },
        "connections" : [ 100, 20, 20, 10, 20]
    }
);

INSERT INTO users3 VALUES (
    1,
    {
        "income" : null,
        "address": {
            "street" : "everywhere",
            "city": "San Fransisco",
            "state" : "CA",
            "phones" : [ 
                { "area":408, "number":50, "kind":"work" },
                { "area":408, "number":60, "kind":"home" },
                "4083451232"
            ]
        },
        "expenses" : { "housing" : 1000, "travel" : 300 },
        "connections" : [ ]
    }
);

INSERT INTO users3 VALUES (
    2,
    {
        "income" : 2000,
        "address": {
            "street" : "nowhere",
            "city": "San Jose",
            "state" : "CA",
            "phones" : [ ]
        },
        "expenses" : null,
        "connections" : null
    }
);

INSERT INTO users3 VALUES (3,{});

INSERT INTO users3 VALUES (
    4,
    {
        "address": {
            "street" : "top of the hill",
            "city": "San Fransisco",
            "state" : "CA",
            "phones" : { "area":408, "number":50, "kind":"work" }
        },
        "expenses" : { "housing" : 1000, "travel" : 300},
        "connections" : [ 30, 5, null ]
    }
);

INSERT INTO Users3 VALUES (
    5,
    {
        "address": {
            "street" : "end of the road",
            "city": "Portland",
            "state" : "OR"
        }
    }
);

次に索引の例を示します。

例9-22 単純索引

CREATE INDEX idx1 ON Users2 (income);

Users表にユーザーごとに1つのエントリを持つ索引が作成されます。エントリには、行によって表されるユーザーの所得とIDが含まれています。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 1000, 0 ]
[ 2000, 2 ]
[ NULL, 1 ]

前述のcreate index文でWITH NO NULLS句が使用された場合、前述の3つのエントリの最後のエントリは索引に表示されません。

例9-23 単純索引

CREATE INDEX idx2 ON Users2 (address.state, address.city, income);

Users表にユーザーごとに1つのエントリを持つ索引が作成されます。エントリには、行によって表されるユーザーの州、市、所得およびIDが含まれます。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ "CA", "San Fransisco", NULL, 1 ]
[ "CA", "San Jose", 2000, 2 ]
[ "MA", "Boston", 1000, 0 ]

例9-24 単純索引

CREATE INDEX idx3 ON Users2 (expenses.books);

ユーザーごとに索引エントリを作成します。このエントリには、ユーザーが書籍への支出を記録する場合は、ユーザーの書籍への支出が含まれ、expensesにbooksエントリがない場合はEMPTY、expensesマップが一切存在しない場合(expenses列の値がNULLである場合)はNULLが含まれます。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 20, 0 ]
[ EMPTY, 1 ]
[ NULL, 2 ]

前述のcreate index文でWITH NO NULLS句が使用された場合は、前述の3つのエントリの最初のエントリのみが索引に表示されます。

例9-25 単純索引

CREATE INDEX idx4 ON users2 (expenses.housing, expenses.travel);

ユーザーごとに索引エントリを作成します。エントリには、ユーザーの住居費用、またはユーザーが住宅費用を記録しない場合はEMPTY、およびユーザーの出張費用、またはユーザーが出張経費を記録しない場合はEMPTYが含まれます。expensesがNULLの場合、索引エントリの両方のフィールドがNULLになります。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 1000, 300, 1 ]
[ 1000, EMPTY, 0 ]
[ NULL, NULL, 2 ]

例9-26 複数キー索引

CREATE INDEX midx1 ON Users2 (connections[]);

接続配列の要素の索引を作成します。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 10, 0 ]
[ 20, 0 ]
[ 100, 0 ]
[ EMPTY, 1 ]
[ NULL, 2 ]

前述のCREATE INDEX文でWITH NO NULLS句が使用されていた場合、前述のエントリの最後の2つは索引に表示されません。

例9-27 複数キー索引

CREATE INDEX midx2 ON Users2 (address.phones[].area, income);

ユーザーの市外局番と収入の索引を作成します。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 408, 1000, 0 ]
[ 408, NULL, 1 ]
[ 415, 1000, 0 ]
[ EMPTY, 2000, 2 ]
[ NULL, 1000, 0 ]

例9-28 複数キー索引

CREATE INDEX midx3 ON Users2
    (address.phones[].area, address.phones[].kind, income);

ユーザーの市外局番、電話番号の種類および収入の索引を作成します。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ 408, "work", 1000, 0 ]
[ 408, "home", NULL, 1 ]
[ 408, "work", NULL, 1 ]
[ 415, "work", 1000, 0 ]
[ EMPTY, EMPTY, 2000, 2 ]
[ NULL, "home", 1000, 0 ]

例9-29 複数キー索引

CREATE INDEX midx4 ON Users2 (
    expenses.keys(), expenses.values());

費用マップのフィールド(キーと値の両方)に索引を作成します。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ "books", 50, 0 ]
[ "clothes", 230, 0 ]
[ "housing", 1000, 0 ]
[ "housing", 1000, 1 ]
[ "travel", 300, 1 ]
[ NULL, NULL, 2 ]

例9-30 単純型指定のjson索引

CREATE INDEX jidx1 ON users3(info.income AS INTEGER);

Users表にユーザーごとに1つのエントリを持つ索引が作成されます。エントリには、行によって表されるユーザーの所得とID (主キー)が含まれています。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 1000, 0 ]
[ 2000, 2 ]
[ EMPTY, 4 ]
[ EMPTY, 5 ]
[ JNULL, 1 ]
[ NULL, 3 ]

例9-31 単純型指定のjson索引

CREATE INDEX jidx1u ON users3 (
    info.income AS ANYATOMIC);

型なしの索引がinfo.incomeに作成されます。この索引の内容は、前述のjidx1と同じですが、値1000と200は整数ではなく数値として格納されます。次の行がusers3表に追加されている場合:

INSERT INTO users3 VALUES (
    6,
    {
        "address": {},
        "expenses" : {},
        "connections" : []
    }
);

The index will look like this:

    [ "none", 6 ]
    [ EMPTY,  5 ]
    [ EMPTY,  4 ]
    [ NULL,   3 ]
    [ 2000,   2 ]
    [ JNULL,  1 ]
    [ 1000,   0 ]

例9-32 単純型指定のjson索引

CREATE INDEX jidx2 ON users3 (
    info.address.state AS STRING,
    info.address.city AS STRING,
    info.income AS INTEGER);

Users表にユーザーごとに1つのエントリを持つ索引が作成されます。エントリには、行によって表されるユーザーの州、市、所得およびID (主キー)が含まれています。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ "CA", "San Fransisco", EMPTY, 4 ]
[ "CA", "San Fransisco", JNULL, 1 ]
[ "CA", "San Jose", 2000, 2 ]
[ "MA", "Boston", 1000, 0 ]
[ "OR", "Portland", EMPTY, 5 ]
[ NULL, NULL, NULL, 3 ]

例9-33 単純型指定のjson索引

CREATE INDEX jidx3 ON users3 (
    info.expenses.books AS INTEGER);

ユーザーごとに索引エントリを作成します。このエントリには、ユーザーが書籍への支出を記録する場合は、ユーザーの書籍への支出が含まれ、expensesにbooksエントリがない場合またはexpensesマップが一切存在しない場合はEMPTY、infoが一切存在しない場合(info列の値がNULLである場合)はNULLが含まれます。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 20, 0 ]
[ EMPTY, 1 ]
[ EMPTY, 2 ]
[ EMPTY, 4 ]
[ EMPTY, 5 ]
[ NULL, 3 ]

例9-34 単純型指定のjson索引

CREATE INDEX jidx4 ON users3 (
    info.expenses.housing AS INTEGER,
    info.expenses.travel AS INTEGER);

ユーザーごとに索引エントリを作成します。エントリには、(a)ユーザーの住居費用、あるいはユーザーが住宅費用を記録しないまたはexpensesフィールドが一切存在しない場合はEMPTY、および(b)ユーザーの出張費用、あるいはユーザーが出張経費を記録しない場合またはexpensesフィールドが一切存在しない場合はEMPTY、のように2つのフィールドが含まれます。infoがNULLの場合、索引エントリの両方のフィールドがNULLになります。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 1000, 300, 1 ]
[ 1000, 300, 4 ]
[ 1000, EMPTY, 0 ]
[ EMPTY, EMPTY, 2 ]
[ EMPTY, EMPTY, 5 ]
[ NULL, NULL, 3 ]

例9-35 複数キー型指定のjson索引

CREATE INDEX jmidx1 ON users3 (
    info.connections[] AS INTEGER);

接続配列の要素の索引を作成します。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 5, 4 ]
[ 10, 0 ]
[ 20, 0 ]
[ 30, 4 ]
[ 100, 0 ]
[ EMPTY, 1 ]
[ EMPTY, 5 ]
[ JNULL, 2 ]
[ JNULL, 4 ]
[ NULL, 3 ]

例9-36 複数キー型指定のjson索引

CREATE INDEX jmidx2 ON users3 (
    info.address.phones[].area AS INTEGER,
    info.income AS INTEGER);

ユーザーの市外局番と収入の索引を作成します。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 408, 1000, 0 ]
[ 408, EMPTY, 4 ]
[ 408, JNULL, 1 ]
[ 415, 1000, 0 ]
[ EMPTY, 2000, 2 ]
[ EMPTY, EMPTY, 5 ]
[ EMPTY, JNULL, 1 ]
[ JNULL, 1000, 0 ]
[ NULL, NULL, 3 ]

例9-37 複数キー型指定のjson索引

CREATE INDEX jmidx2u ON users3 (
    info.address.phones[].area AS ANYATOMIC,
    info.income AS INTEGER);

これはjmidx2索引のバリエーションで、最初の索引パスは型指定されず、2番目の索引パスが型指定されています。jmidx2とjmidx2uの内容は同じですが、jmidx2uの場合は最初の列の数値が整数ではなく数値として格納されます。

例9-38 複数キー型指定のjson索引

CREATE INDEX jmidx3 ON users3 (
    info.address.phones[].area AS INTEGER,
    info.address.phones[].kind AS string,
    info.income AS INTEGER);

ユーザーの市外局番、電話番号の種類および収入の索引を作成します。Users3のサンプル行のこの索引の内容は、次のとおりです。

[ 408, "home", JNULL, 1 ]
[ 408, "work", 1000, 0 ]
[ 408, "work", EMPTY, 4 ]
[ 408, "work", JNULL, 1 ]
[ 415, "work", 1000, 0 ]
[ EMPTY, EMPTY, 2000, 2 ]
[ EMPTY, EMPTY, EMPTY, 5 ]
[ EMPTY, EMPTY, JNULL, 1 ]
[ JNULL, "home", 1000, 0 ]
[ NULL, NULL, NULL, 3 ]

例9-39 複数キー型指定のjson索引

CREATE INDEX jmidx4 ON users3 (
    info.expenses.keys(),
    info.expenses.values() AS INTEGER);

費用マップのフィールド(キーと値の両方)に索引を作成します。索引定義のkeys()部分は型を宣言できません。これは、型が常に文字列であるためです。Users2のサンプル行のこの索引の内容は、次のとおりです。

[ "books", 50, 0 ]
[ "clothes", 230, 0 ]
[ "housing", 1000, 0 ]
[ "housing", 1000, 1 ]
[ "housing", 1000, 4 ]
[ "travel", 300, 1 ]
[ "housing", 1000, 4 ]
[ EMPTY, EMPTY, 2 ]
[ EMPTY, EMPTY, 5 ]
[ NULL, NULL, 3 ]