はじめに
OCIのOracle NoSQL Database Cloud Service(NDCS)では、子表という機能を使って、テーブルに階層を持たせることが可能になっています。
Oracle NoSQL DatabaseはSQLが利用できるため、この機能を使うと、RDBほどではありませんがテーブル同士の関連性を表現できます。
子表の作成
子表の作成のためには親となるテーブルの作成がまず必要です。
メニュー -> データベース -> 表 と選択して、NDCSを開きます。
「表の作成」から親となるテーブルを作成します。
ここではparent
と言う名前のテーブルで、id(String), Value(String)だけを持つテーブルを作ってみます。
テーブルが作成されたらクリックして開くと、左メニューに「子表」とあるのでクリックします。
同じようにテーブルが作れます。
注目すべきは「名前」の所にparent.
と既に記述があるところです。Oracle NoSQLでは、子テーブルは.
で繋いで表現をします。
同じカラム名は持てないので、child1_
を接頭辞的につけています。
アクティブになったので確認してみると、列に設定していないはずのid
列が出てきました。
これはつまり親であるparent
テーブルの主キーを継承していることになり、子であるchild1
テーブルは複合主キーとして振舞うということが分かります。
データを挿入
parent.child1
テーブルにデータを挿入してみます。
「データの探索」からSQLが実行できるので、INSERT文を実行してみましょう。
以下のようにINSERT文を2つ実行します。どのテーブルに対してもクエリの実行は可能です。
INSERT INTO parent VALUES ("2023040001", "parent example1")
INSERT INTO parent.child1 VALUES ("2023040001", "2023040001-1", "child1 example1")
クエリの実行
子表はテーブルとして独立して利用できます。データを取得してみましょう。
SELECT * FROM parent.child1
次は親テーブルのデータを取得してみましょう。
SELECT * FROM parent
parent.child1のデータは取得されないことが分かります。
これこそがこの子表のメリットです。必要のないデータを設計レベルでそもそも取得しないようにすることが可能です。
テーブルが大きくなりすぎている場合などに利用できそうです。
勿論、必要に応じて親テーブル + 子テーブルのようにデータを取得することも可能です。
Oracle NoSQLの子表ではLEFT OUTER JOINがサポートされています。
SELECT p.id, c1.child1_value
FROM parent p LEFT OUTER JOIN parent.child1 c1
on p.id = c1.id
テーブルの階層
子表にはさらに子表を作ることが可能です。
parent.child1
テーブルと同じようにid
とvalue
だけを持つparent.child1.grandchild1
テーブルを作ってみます。
さらに、parent.child1
テーブルと同じ階層にparent.child2
テーブルを作ります。
テーブルの階層は以下のようになります。
parent
├ child1
│ └ grandchild1
└ child2
SQLを実行して作成した2つのテーブルに対してデータを挿入します。
INSERT INTO parent.child1.grandchild1 VALUES ("2023040001", "2023040001-1", 2023040001-1-1, "grandchild1 example1")
INSERT INTO parent.child2 VALUES ("2023040001", "2023040001-2", "child2 example1")
しかし、2つ以上のLEFT OUTER JOINはサポートされていません。
SELECT p.id, p.value, c1.child1_value, c2.child2_value
FROM parent p
LEFT OUTER JOIN parent.child1 c1 ON p.id = c1.id
LEFT OUTER JOIN parent.child2 c2 ON p.id = c2.id
そのような場合はNESTED TABLES句を利用します。
descendants
句と同時に利用して、descendants
の後の括弧内のテーブルが子の関係にあることを表現します。
SELECT p.id, p.value, c1.child1_value, c2.child2_value
FROM NESTED TABLES (parent p descendants(parent.child1 c1, parent.child2 c2))
これを利用すれば、孫(もしくはそれ以降)の関係にあるテーブルの同時取得も可能になります。
SELECT p.id, p.value, c1.child1_value, c2.child2_value, gc1.grandchild1_value
FROM NESTED TABLES (parent p descendants(parent.child1 c1, parent.child2 c2, parent.child1.grandchild1 gc1))
まとめ
今回はOCIのNoSQL Database(NDCS)を使って、テーブル階層を試してみました。
これを使うことで、より柔軟なデータモデルの設計や、データ取得量の軽減によるコスト(スループット)の節約に活用できそうです。
参考資料
https://blogs.oracle.com/nosql/post/table-hierarchy-nosql-cloud
https://docs.oracle.com/en/database/other-databases/nosql-database/22.3/index.html