slim3(App Engine/Java)のお勉強をしながら、良くあるパターンのブログサービス的なWEBアプリケーションを作っています。
ブログサービスの概念モデリングは、[ブログ] – [記事] – [コメント] の 3階層で Header-Detailになる事が多いと思います。
今までRDBMSばっかりやってたのですが、過去は3層で考えた概念スキーマをそのまま論理スキーマにしちゃって問題無かったです。
と言うか今でも私は正規化バンザイ派、概念スキーマをそのまま論理スキーマにしちゃえ派です。このへんは佐藤正美さんのT字形ER手法に強く影響されました。
で、App Engineで作ろうとするじゃないですか。
時間が作れ次第おっかなびっくりやっているので遅々として進まない訳ですが。
まずは記事のCRUDを作ってみて、それは上手くいきました。
で、最近やっと後回しにしていたリレーションシップとトランザクションに取り掛かっているわけです。
「Google App Engine (のKVS)では非正規化を恐れるな」なんて聞いていたものですから、記事Entityの親にあたるブログEntityについては、記事Entityの中に「ブログ名」として繰り返し項目にしちゃえばいいかと、結構簡単に考えていました。
で、いざやってみると、使い物にならない感じなんですね。
まず、記事Entity内で繰り返し項目になっちゃった「ブログ名」を、Distinctして取得したいと思ったんですが、Slim3では(App Engineでは)出来ません。
ならばGroup By で、とも思ったんですが、それもありません。
マニュアルは一度読んでるし、GAEの本も2冊ばかり読んだんですが・・・なんとなく判った気でいるのと、実際に手を動かして困ってみるのとでは、頭に入り方が大違いですね。
ならばと、Slim3の機能を使ってブログEntityと記事Entityを双方向1対多関連にしました。
これで目出度く ブログの一覧は取得出来る様になりました。当たり前ですが。
仕様として、記事Entityは、親であるブログEntity(カテゴリ)の変更というか、付け替えが出来ます。
普通にトランザクションでこれをやろうとすると、com.google.apphosting.api.ApiProxy$ApplicationException がスローされました。
これは自分のコードの書き方が悪いだけでして、異なるEntity Group での更新をしようとした事が原因、という事まではすぐに判りました。
本題はココからでして・・・
ブログEntityはオーナーだけが変更できます。
記事もオーナーだけが書けます。
RDBMS脳では、[ブログ] – [記事] – [コメント] の 3階層 の外側に、[オーナー]Entityがいて、[ブログ]の外部キーになっているか、[オーナー・ブログ]連関テーブルがあるか、そんな感じです。
App Engineでは同一Entityグループでしかトランザクションが使えない。
Entityグループが同一なら物理的な格納位置が近くなる(らしい)。
もしかして、[オーナー]でEntityグループをくくった方が良いのか????
[オーナー] – [ブログ] – [記事] – [コメント] の 4階層???
Hibernate的に考えると、オーナークラスのプロパティでブログをSetとかのコレクションクラスで持たせてlazy loadingさせて、あとは記事、コメントと・・・そんな感じ?
それでスケールするのか・・・・?
この4階層の論理スキーマで良いのか、自信が持てないです。 <- イマココ 幸い、Slim3には「グローバル・トランザクション」なるものがあり、異なるEntity Group間での更新も出来る筈です。(まだ試していない) 一貫性を重視するか、スケーラビリティを重視するかで、論理スキーマが変わってきそうな気がします。 もうしばらく悩みそうです。