CloudSQLのERD設計

TemPlat ConsoleではデータベースをDatastore(KVS)とCloudSQL(RDB)から選択出来ます。
ここではCloudSQL(RDB)を使用した場合のERD設計の勘どころをお話しします。

CloudSQL(RDB)の特徴

CloudSQLはGCPが提供するリレーショナルデータベース(RDB)で、実体はMySQLやPostgreSQLです。
一般的なRDBなので、テーブル間のリレーションが使えます。
他にも検索時などに使用するLIKE検索を行うことが出来たり、SQLを記載してデータを抽出できるので、Datastore(KVS)では難しいテーブル感の複雑な分析を行うSQLを実行できます。
作りたいアプリケーションにLIKE検索やSQLが必要な場合はCloudSQL(RDB)を使用する必要があります。

ただし、コスト面ではDatastoreにかなり劣り、月額のコストが必ず発生します。
また、Datastoreと比べ、全てのクエリでindexが使える訳ではないので、データ量が膨大になってくるとindexを適切に設定しないと動作が重くなる等、データ量に対しての課題も発生しやすいのが特徴です。

CloudSQL(RDB)のテーブル間の連携

CloudSQLのERD設定ではテーブル間の連携として、一対一、一対多、多対多の連携が出来ます。
連携を行うことで、一度のAPI呼び出しで、複数テーブルのデータの取得や登録、更新が出来るようになります。

一対一、一対多、多対多はERD設定時の方法が異なりますので、それらを順を追って説明していきます。

一対一の連携

一対一の連携は親テーブルが子テーブルの内容を一つのみ持っている場合に使用します。

上記はCustomerの詳細情報のCustomerDetailをCustomerが持っているような例です。
この例だと、CustomerDetailの内容をCustomer自体に持たせてもデータ構造上あまり変わりはありませんが、テーブルのカラムが多い場合に整理しやするくするため等に使用できます。

一対一の設定方法

一対一を設定するには、まず子テーブルのCustomerDetailをERDに登録し、次に親テーブルのCustomerの任意のフィールドに「Type」を”struct”にした上で、「StructType」を”CustomerDetail”に設定すれば完了です。

この設定を行うと、CustomerDetailには赤い背景で”CustomerID”というフィールドが追加されます。
これは、CustomerとCustomerDetailを関連づけするためにTemPlatが生成したフィールドで、実際のデータベースにもカラムとして登録されます。

また、Customerに定義したCustomerDetailのフィールドは実際のデータベースのカラムには登録されないという点にも注意してください。
APIではCustomerDetailはCustomerに内包されますが、実際のデータベースではあくまで”CustomerID”で関連づいています。

belongToについて

「StructType」の右側にある「belongTo」にチェックを入れると、従属関係を入れ替えることが出来ます。
ここでは言葉の意味を考える前に、実例を見てみましょう。
下記が「belongTo」にチェックを入れた状態です。

CustomerDetailの赤い背景の”CustomerID”が無くなり、Customerに赤い背景の”CustomerDetailID”というフィールドが追加されています。
このように「belongTo」にチェックを入れるかどうかは”どちらが関連したIDを持つのが適切か”で判断してみてください。
例えば子テーブルがマスタの場合は子テーブルに関連IDを持つのは不適切なので、「belongTo」にチェックを入れることになります。
今回の例のように、どちらが持ってもあまり違和感がない場合はチェックを入れる必要はありません。

noUpdateについて

「StructType」の右側にある「noUpdate」にチェックを入れると、CustomerのAPI呼び出し時にCustomerDetailの登録や更新を行わないようにすることが出来ます。
例えば親テーブルがトランテーブルで子テーブルがマスタテーブルの場合に、親テーブルAPI呼び出し時に間違って子テーブルの内容を書き換えないようにするために使用してください。

一対多の連携

一対多の連携は親テーブルが子テーブルの内容を複数持っている場合に使用します。

上記はCustomerがOrder(注文情報)を複数持っているような例です。
Customer側に配列でOrderを定義することにより、CustomerのAPI呼び出し時にそのCustomerのOrderまで取得することが出来るようになります。

一対多の設定方法

一対多を設定するには、まず子テーブルのOrderをERDに登録し、次に親テーブルのCustomerの任意のフィールドに「Type」を”array”にした上で、「ChildType」を”struct”にし、「StructType」を”Order”に設定すれば完了です。

この設定を行うと、Orderには赤い背景で”CustomerID”というフィールドが追加されます。
これは、一対一の設定でbelongToを使用しないパターンと同様で、実際のデータベースのカラムは全く同一になります。
ただし、API呼び出し時にはOrdersが配列なので、APIのインターフェースは異なった物が生成されます。

また、一対一と同様にCustomerに定義したOrdersのフィールドは実際のデータベースのカラムには登録されないという点にも注意してください。
APIではOrdersはCustomerに内包されますが、一対一と同様に実際のデータベースではあくまで”CustomerID”で関連づいています。

多対多の連携

多対多の連携は二つのテーブルがそれぞれを複数持っている場合にしようします。
なお、多対多の設定方法はいくつかパターンがありますので、データの構造に応じて選択してください。

上記はOrder(注文情報)がMenu(注文したメニュー)を複数持っていて、Menuは他のOrderでも使用されるケースです。
このようにすることでMenuにOrderIDを持たなくともOrderがMenuを複数持てるようになります。

また、OrderとMenuで多対多を実現するために中間テーブルのOrderMenuを定義しています。
多対多を定義する場合はこの中間テーブルが必ず必要となる点に注意してください。

多対多の設定方法

多対多を設定するには、まずそれぞれのテーブルのOrderとMenuを作成し、中間テーブルのOrderMenuを作成します。
なお、OrderMenuテーブルのフィールドはこの段階で定義する必要はありません。

次に、Orderテーブルの任意のフィールドにOrderMenusを定義します。
なお、ここで行う設定は一対多の設定と同じです。

次に、OrderMenuの任意のフィールドにMenuを定義します。
なお、ここで行う設定は一対一のbelongToの設定と同じです。

これで多対多の設定は完了です。
OrderMenuにMenuを定義する際は必ず「belongTo」にチェックを入れてください。
チェックを入れないと一対多の状態と変わらなくなってしまいます。

その他の多対多の設定方法

前述したように、多対多の設定には他にもパターンがあります。
例えば、下記のようにOrderとMenuそれぞれにOrderMenuの配列を持たせることも可能です。

前述している通り、OrderのOrderMenusやMenuのOrderMenusは実際のデータベースのカラムには登録されません。
つまり、先ほど紹介したパターンと今回紹介しているパターンは実際のデータベースのカラムは同一です。

ただし、OrderをAPIで取得した場合に、先程のパターンはMenuまで取得出来るのに対し、こちらのパターンだとOrderMenuまでしか取得出来ません。その代わりにMenuを取得した場合にOrderMenuが取得出来ます。

多対多のまとめ

このように、多対多はデータの構造やAPIの使い方を見据えて、ケースバイケースで設定を行う必要があります。
幸いにもTemPlatではERDの変更が容易に行えるので、色々なパターンで試しながらアプリケーションにあった方式を見つけてください。

また、ここまで紹介した通り、多対多の設定は一対一と一対多の組み合わせで設定を行なっています。
多対多と多対多を組み合わせる等、更に複雑な構造にすることも可能ですので必要に応じて試してみてください。