asatoの技術的な日常日記

「成長に最大の責任をもつ者は、本人であって組織ではない。自らと組織を成長させるためには何に集中すべきかを、自らに問わなければならない」  非営利組織の経営 - ピーター・ドラッカー

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Datastoreのデータモデル設計のふりかえり, パート4

はじめに


パート1パート2を読んでいない方は、この節を読んで下さい。

個人的に趣味で、Goole App Engine/Java(実際はScalaを使用)を使い始めて一年ぐらいになります。そこで、このシリーズでは、Datastoreのこれまでに設計したデータモデルについて少しふりかえりながら、
-設計上の失敗点
-データモデルのパターン(デザインパターンと言う意味ではない)
-データモデルの進化のパターン(プロパティの追加や削除など)
などについて考えていきたいと思っています。

基本的には、JDO使用で、一部、Objectifyを使ってます。

事例として作ってるWebサイトはGoodsHomeというもので、もともとは、新刊の定期自動チェックのために作ってました。今は、モノ(商品)を中心としてファンやユーザーがつながれるようなソーシャルなサイトにしようと思ってます。

現状、Kind数(クラス数)は、47でした。このシリーズでは、これらモデルの中から、単純なモデルから順に見ていきたいと思います。

考察


今回のパートで例にするモデルは、タグです。単に商品にタグを付けれる機能です。各商品に対してタグは10つまで付けられる仕様です。JDO使用です。
kind_Tags.png
TagsとTagの二つのKindがあります。Tagsは、ある商品に付けられたタグの一覧を保持するだけのものです。asinはamazonの商品IDを表します。Tagは個々のタグを表します。nameは、タグ名を、userIdは、このタグを付けたユーザーのIDを(ない場合もある)、dateはタグが付けられた日時を表します。

このモデルに対する操作は、以下です。
(a) エンティティの作成
(b) tagsの更新
(c) tagsの読み取り
(d) nameからasinリストの取得
kind_Tags_op.png



特徴は以下です。
(1) エンティティ間の関係がある。
(1.1) 1対n(one to many)の関係である。
(1.2) 双方向の関係である。
(2) トランザクションは必要である。タグ数の制約を満たす必要がある。
-Tags(Parent)
(3) tags以外の(JDO上の)プロパティがない。
(4) 各エンティティは、(特に理由がなければ設計上は)削除されない。
-Tag(Child)
(5) 各プロパティは、読み取り専用である。
(6) 各エンティティは、削除される。
(7) Tags(Parent)への関係をもつ。

下記の図は、上記のようなモデルをより一般的に表したものです。

ds_patten4.png


設計について


今回のモデルに限りませんが、設計する上で考慮の必要性が高いように思える順番は以下です。

(1) トランザクションの必要の有無。

(2) 性能。といっても、性能の測定や試験はほとんどしていません。

(3) クエリのやりやすさ。やりやすくなるようにプロパティを持たせます。

(4) 仕様変更への対応のしやすさ。個人的にはそれほど今のところ考慮して設計していませんが、何度かデータモデルの変更の必要性に出くわしました。変換作業は、結構面倒な印象があります。

(5) データ容量。データの重複をなくすることを優先しません。課金で対応します。たとえば、私の場合、現状、エンティティ数:10,480,242(1000万)、使用容量:12.03 of 15.00 GBytes、課金:$0.06 です。


パート5に続く。


付録:データモデルのパターン


パート1で特定したデータモデルのパターン
kind_patten1.png

パート2で特定したデータモデルのパターン
kind_patten2.png


パート3で特定したデータモデルのパターン
ds_patten3.png

パート4で特定したデータモデルのパターン
ds_patten4.png

スポンサーサイト

Datastoreのデータモデル設計のふりかえり, パート3

はじめに


パート1パート2を読んでいない方は、この節を読んで下さい。

個人的に趣味で、Goole App Engine/Java(実際はScalaを使用)を使い始めて一年ぐらいになります。そこで、このシリーズでは、Datastoreのこれまでに設計したデータモデルについて少しふりかえりながら、
-設計上の失敗点
-データモデルのパターン(デザインパターンと言う意味ではない)
-データモデルの進化のパターン(プロパティの追加や削除など)
などについて考えていきたいと思っています。

基本的には、JDO使用で、一部、Objectifyを使ってます。

事例として作ってるWebサイトはGoodsHomeというもので、もともとは、新刊の定期自動チェックのために作ってました。今は、モノ(商品)を中心としてファンやユーザーがつながれるようなソーシャルなサイトにしようと思ってます。

現状、Kind数(クラス数)は、47でした。このシリーズでは、これらモデルの中から、単純なモデルから順に見ていきたいと思います。

考察


今回のモデルは、商品のブックマークを表すモデルです。各ユーザーは、商品IDをもとに、その商品をブックマークできます。このモデルは、Datastoreに慣れていない初期に作ったモデルです。
kind_Bookmarks.png
BookmarksとBookmarkの二つのKindを定義しました(JDOを使用)。Bookmarkは、各商品を対象としたブックマークを表します。asinは、amazonの商品IDです。userIdは、ブックマークしたユーザのIDを表します。Bookmarksは、単にuserIdごとに、Bookmarkの一覧を保持するだけのものです。

なお、JDOを使用しているので上記のようにモデルを表していますが、実際には、Datastore上では、以下のようにデータが保存されますので注意してください(詳しくはGAEのドキュメントを参照)。
ds_ss1.png
ds_ss2.png



このモデルに対する操作は、三つです。
(a) エンティティの作成
(b) bookmarksの更新
(c) bookmarksの読み取り

特徴は以下です。
(1) エンティティ間の関係がある。1対nの関係。
(2) トランザクションは必要である。
-Bookmarks(Parent)
(3) bookmarks以外の(JDO上の)プロパティがない。
(4) 各エンティティは、(特に理由がなければ設計上は)削除されない。
-Bookmark(Child)
(5) 各プロパティは、読み取り専用である。
(6) 各エンティティは、削除される。


下記の図は、上記のようなモデルをより一般的に表したものです。
ds_patten3.png


設計上の悩み


設計上失敗していると感じるのは、Bookmarksがなぜ必要なのか、という点です。不要な理由はあります。
-性能上の欠点: ブックマークの追加や削除が行われるとindexのプロパティ値の更新が発生する

そもそも、なぜ現状のようなモデル設計になっているかというと、不慣れだったこともありますが、ユーザーIDをもとにブックマークの一覧どのように保持・取得するかという観点から、現状のモデルを思いついた(それ以外は思いつけなかった)ということがあります。

実は、現状のモデルはバージョン2で、バージョン1では、BookmarkはuserIdを保持していませんでした。変更した理由は、性能上の理由と言うよりは、クエリの行いやすさの理由だった気がします。あるユーザーがその商品をブックマークしているかどうかを
userId == '%s' && asin == '%s'
のようにクエリできるようにしたかったからです。
kind_Bookmarks_v1_2.png

ちなみに次のバージョンでは、Bookmarksを削除する予定です。それと、ブックマークした日時を保存するプロパティの追加も検討しています。
kind_Bookmarks_v_2_3_4.png



パート4に続く。


付録:データモデルのパターン


パート1で特定したデータモデルのパターン
kind_patten1.png

パート2で特定したデータモデルのパターン
kind_patten2.png


パート3で特定したデータモデルのパターン
ds_patten3.png

Datastoreのデータモデル設計のふりかえり, パート2

はじめに


パート1を読んでいない人は、この節を読んで下さい。

個人的に趣味で、Goole App Engine/Java(実際はScalaを使用)を使い始めて一年ぐらいになります。そこで、このシリーズでは、Datastoreのこれまでに設計したデータモデルについて少しふりかえりながら、
-設計上の失敗点
-データモデルのパターン(デザインパターンと言う意味ではない)
-データモデルの進化のパターン(プロパティの追加や削除など)
などについて考えていきたいと思っています。

基本的には、JDO使用で、一部、Objectifyを使ってます。

事例として作ってるWebサイトはGoodsHomeというもので、もともとは、新刊の定期自動チェックのために作ってました。今は、モノ(商品)を中心としてファンやユーザーがつながれるようなソーシャルなサイトにしようと思ってます。

現状、Kind数(クラス数)は、47でした。この中の単純なモデルから順に見ていきたいと思います。

考察


パート2では、WishTagというデータモデルを事例にして考えていきたいと思います。このモデルは、ある商品を欲しいと思ったユーザー数(正確には思った回数)を表すものです。facebookの「イイネ!」ボタンと同じような機能です。ユーザーが「欲しい!」ボタンをクリックすると、カウントが一つ増えます。

kind_WishTag.png

プライマリキーは、asin(amazonの商品ID)です。countはクリック数を表します。ちなみに、現状、1,800程度のエンティティがあります。

このモデルに対する操作は、三つです。
(a) エンティティの作成
(b) countの更新
(c) countの読み取り

特徴は以下です。
(1) 他のエンティティへの関係を持たない(Key経由でも持たない)。
(2) プロパティは、更新/読み取りされる。
(3) 各エンティティは、(特に理由がなければ設計上は)削除されない。
(4) トランザクションは必要である。

下記の図は、上記のようなモデルをより一般的に表したものです。
kind_patten2.png

設計上の悩み



設計上の悩みは、どのユーザー(ユーザー登録している者としていない者)がいつクリックしたのかを示す情報がないことです。つまりこのような情報を保存するような仕様への変更が出た時、データモデルをどう変更するのか? を考える必要があります。新たなKindを定義することなく、単にプロパティを追加するような変更では対応できないと考えます。


パート3に続く。


付録:データモデルのパターン


パート1で特定したデータモデルのパターン
kind_patten1.png

パート2で特定したデータモデルのパターン
kind_patten2.png

Datastoreのデータモデル設計のふりかえり, パート1

はじめに


個人的に趣味で、Goole App Engine/Java(実際はScalaを使用)を使い始めて一年ぐらいになります。そこで、Datastoreのこれまでに設計したデータモデルについて少しふりかえりながら、
-設計上の失敗点
-データモデルのパターン
-データモデルの進化のパターン(プロパティの追加や削除など)
などについて考えていきたいと思います。

基本的には、JDO使用で、一部、Objectifyを使ってます。

事例


事例として作ってるWebサイトはGoodsHomeというもので、もともとは、新刊の定期自動チェックのために作ってました。今は、モノ(商品)を中心としてファンやユーザーがつながれるようなソーシャルなサイトにしようと思ってます。

さて、現状、Kind数(クラス数)は、47でした。この中の単純なモデルから順に見ていきたいと思います。

まずは、NewItemというモデルです。これは、商品が新たに見つかった時の情報を表すモデルです。新たな商品データがあるかどうかは、タスクを使って定期チェックされます。

kind_NewItem.png

図のPKは、プライマリキーのことです。PKの値はasinで、これは、amazonの商品IDです。categoryは、商品のカテゴリ(書籍やおもちゃなど)を表しています。dateは、見つかった日時を表します。ちなみに、152,000のエンティティがあります。

モデルに対する操作は、二つです。
(a) エンティティの作成
(b) カテゴリごとに新着順にエンティティの読み取り(select from NewItem where category == '%s' order by date desc)。

特徴は以下です。
(1) 他のエンティティへの関係を持たない(Key経由でも持たない)。
(2) 各プロパティは、読み取り専用である。
(3) 各エンティティは、(特に理由がなければ設計上は)削除されない。
(4) トランザクションは不要である。

上記の図と同じですが、下記の図では、プロパティが読み取り専用という点を強調してみました。
kind_NewItem2.png

最後に、下記の図は、上記のようなモデルをより一般的に表したものです。

kind_patten1.png


さて、何らかの設計ミスを感じているかどうかですが、それは、他のモデルの紹介時にまた考えたいと思います。


次回に続く。


FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。