ER図とGoogle App Engine
最近の趣味プログラミングでは、ER図からGAEj用のEntityクラスとDaoクラスを自動生成するプログラムを作っている。
少し前に書いた日記で、「RDBMSでのユニークFKをGAEでのキーに持ってきた方が良い」みたいなことを書いたけれども、ER図で言うと、「(1)対(0または1)」のリレーションが貼られた部分が、それにあたる。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン1
class A - a (PK) NOT NULL
class B - b (PK) NOT NULL - a (FK01->A) NOT NULL
A | : | B |
1 | : | 0または1 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
上記みたいな場合である。
ちなみにリレーション対象のフィールドが複数あっても、複数個の型違いの変数からシリアライズ文字列は作れるので、そのシリアライズ文字列をキーにすれば良い。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン2
class A2 - a (PK) NOT NULL - a2 (PK) NOT NULL
class B2 - b (PK) NOT NULL - a (FK01->A2) NOT NULL - a2 (FK01->A2) NOT NULL
A2 | : | B2 |
1 | : | 0または1 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
じゃあ、次のようなパターンはどうすれば良いだろうか。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン3
class X - x (PK) NOT NULL
class Y - y (PK) NOT NULL
class Z - z (PK) NOT NULL - x (FK01->X) NOT NULL - y (FK02->Y) NOT NULL
X | : | Z |
1 | : | 0または1 |
Y | : | Z |
1 | : | 0または1 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
これはたぶん、できない。
以下の様に書き直すしかない。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン4
class X - x (PK) NOT NULL - z (FK01->Z) NULLABLE
class Y - y (PK) NOT NULL - z (FK02->Z) NULLABLE
class Z - z (PK) NOT NULL
X | : | Z |
1 | : | 0または1 |
Y | : | Z |
1 | : | 0または1 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
「なんだ、パターン1よりパターン4のほうが、自由度が高いんじゃないか! パターン1は必要ないね!」
と思ったら、大間違い。
パターン1のAに、仮想エンティティ(データベース上にエンティティの種類さえ本当は存在しないけれども、存在しているものと過程してER図上には表記する)を用いてやることで、「ユーザが自由入力の文字列ID」や「とあるIDのスレッドのn発言目」といった、出現頻度の高いユニーク制約の多くを、ER図上で表現することができる。
逆にパターン4は、ほとんど使わない。
(新しいエンティティを足すのに、2つもエンティティを操作しなければならないというのが、このパターンがGAEでほとんど使われない理由。別々のエンティティグループなら2回の操作は別々のトランザクションで行われることになるし、同じエンティティグループにしなければならないという制限は、それはそれで大きな制限になる場合が少なくない)
最後に、パターン3と良く似ている様で全然違う、以下のパターン。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン5
class X - x (PK) NOT NULL
class Y - y (PK) NOT NULL
class Z - z (PK) NOT NULL - x (FK01->X) NOT NULL - y (FK01->Y) NOT NULL
X | : | Z |
1 | : | 0以上 |
Y | : | Z |
1 | : | 0以上 |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
これはGAE上で実装可能なのだが、ER図上は何とも書きづらい。
そういう時は、ER図上では以下の様に表現する。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
■パターン6
class X - x (PK) NOT NULL
class Y - y (PK) NOT NULL
class W (コメント:仮想エンティティ) - x (PK) NOT NULL (コメント:FK01->X) - y (PK) NOT NULL (コメント:FK01->Y)
class Z - z (PK) NOT NULL - x (FK01->W) NOT NULL - y (FK01->W) NOT NULL
X | : | W |
1 | : | Y個 |
Y | : | W |
1 | : | X個 |
W | : | Z |
1 | : | 0または1 |
(※ WはXとYのクロス積個、仮想的に存在しているものとみなす)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ね、仮想エンティティ、便利でしょ。