ERD設計の勘どころ【Datastore編】

プロジェクトを作成したら、まずアプリケーションのテーブルを定義しましょう。ここではERD設計の勘どころをお話しします。データベースとしてはGoogle Cloud Platform(GCP)環境のデータストア(Datastore)を利用するケースで説明します。

基本的な操作方法

TemPlatでのERD作成の基本的な操作方法に関しては、動画解説を作っているのでこちらを参考にしてください!実際にご自身でERDを作りながら読んで下さい。

Datastore(KVS)の特徴

世の中では、データベースとしてはリレーショナルデータベース(RDB)が一番ポピュラーかと思います。TemPlatではRDBも使えますが、コスト面も考えるとKVSのDatastoreがお勧めです。

KVSではRDBのようなテーブル間のリレーションが使えないので、ERDを設計する際に考慮が必要です。更新処理に関してはRDBと大きな違いはなく基本1レコードづつ操作するのであまり考慮は必要ありませんが、データを参照する際に注意が必要です。

Datastoreでの関連テーブルの取得方法

RDBでは関連するテーブルのデータを参照する際には、SELECT文めリレーション(join)を使って親テーブルと一緒に子テーブルのレコードも参照できます。ですがDatastoreではそのjoinが使えません。それぞれのテーブルを別々にSELECTする必要があります。この参照のやり方を意識してERDを考えておく必要があります。

以下によく使うパターンを紹介します。

子供が親を知っているパターン

これはRDBでも利用するパターンですが、一番利用するパターンが子テーブル側に親のキーを持つパターンです。こらは親と子が1:nの関係を持つ場合によく使います。

APIでの参照方法。親のKeyをもらってそのKeyを条件に子テーブルを検索。

Datastoreは特定カラムの値で複数件のSELECTが可能。

常に親子をセットで参照するなら、親のget(Key指定で1レコード取得)の際に、子テーブルから関連レコードを複数件取得して一緒に返す。

親が子供のID一覧を持っている

2つ目のパターンは親が子テーブルのID一覧を配列としてもつケースです。これはRDBでは関連テーブルを間に持つような、親と子がN:Nになるようなケースなどで利用することが考えられます。

以下の例だとプロジェクトに複数のメンバーが所属するようなケースですね。ユーザは複数のプロジェクトに所属できるので、子供が親のIDを持つ1つ前のパターンは使いづらいですね。

この場合は、子供の一覧を取得する場合には、親テーブルが持つ子テーブルの複数のIDを指定して「multiGet」というDatastoreの検索方法を使って、複数IDをまとめて取得することができます。

子テーブルをStructとして持つパターン

ここまではTable間のリレーションの持たせ方を話してきましたが、Datastoreにはもう一つ方法があります。それがstructです。RDBだとあまり馴染みないですが、別のレコードを1カラムとして持つというか、JSON構造のデータ型が使えるようなものですかね。

上の例では、商品が複数のオプションを持つことができるのをStructの配列で保持しています。Structを配列で持つこともできますし、1件のみ持つこともできます。Structの場合は、親テーブルのレコードの一部であるので、1回のSELECTで取得できます。更新するときも同様に親テーブルのレコードの一部としてまとめてINSERTやUPDATEDができます。

注意する点としては、親レコードの一部なので、Structの1レコードのみをINSERTやUPDATEすることはできないというものです。これはシステムの利用者が複数いて、同時に更新する可能性が高いテーブルでは注意が必要です。

親レコードの単位でしか更新できないので、「同時更新ができない」、「排他制御を考慮しないと、他の人の更新を消してしまう」などの課題がでてくることがあります。この辺は別の記事として書きたいと思います。

DatastoreのKeyのIDとNameに関して

Datastoreの各レコードにはテーブル内で一意となる「Key」が必要です。このKeyですが実は2種類のパターンがあります。IDとNameがその2つです。

IDは整数型で、自動採番も可能なKeyです。特にKeyに意味をもたせる必要がなければ基本このIDを使うのが楽です。INSERTする際にIDを未指定にしておけばDatastoreが勝手に採番してくれます。また、アプリ側でIDを指定してあげることもできますがあまり使うシーンはないかと思います。

もう一つのNameは文字列型で、こちらは必ずアプリ側で指定してINSERTする必要があります。何か要件的にルールが決まっていて、それをKeyとして利用したい場合に使います。番号体型をコード化しているような場合に使われますね。

例えば、「商品コード」とか「社員番号」などがあるかと思います。あとは、外部システムで既に採番されているものなどもありえますね。

TemPlatのERD作成では、デフォルトでIDが使われますが、もちろんNameをKeyに使うことも可能です。