私は google-app-engine と google datastore (bigtable) の初心者であり、必要なデータ モデルを設計するための最良のアプローチがどれであるかについて疑問があります。
製品カタログのような階層モデルを作成する必要があります。各ドメインには深いサブドメインがあります。現時点では、製品の構造は読み取り要件よりも変更が少ないです。ワインの例:
- 起源(トスカーナ、プリオラート、アルザス)
- ワイナリー (1 つのオリジンのみに属します)
- ワイン(1つのワイナリーのみに属します)
すべての関係はバラバラで不完全です。さらに、要件の順序で、おそらくすべてのワインに使用するカウンターを保存する必要があります (トランザクションが必要になる場合があります)。
ドキュメントの順に、さまざまな潜在的な解決策があるようです。
- 先祖管理。親関係とトランザクションの使用
- 疑似祖先管理。db.ListProperty(db.Key) を使用した祖先のシミュレート
- 参照プロパティ。クラス間の関係を明示的に指定する
しかし、ワインを取得するために予想される要求の順序で... 時には品種ごと、時には原産地ごと、時にはワイナリーごとに...これらの構造を使用したクエリの動作が心配です(リレーショナルモデルの複数の結合のように.ファミリの製品を要求する場合...製品ツリーの最終ディープ クオリファイアに参加し、ファミリ以降に参加する必要があります)
重複した情報を作成する方が良いかもしれません (Google チームの推奨事項の順序: 操作にはコストがかかりますが、ストレージはそうではないため、重複したコンテンツは主な問題とは見なされません)。
他の同様の質問に対するいくつかの回答は、次のことを示唆しています。
- すべての親 ID を文字列の階層として保存します...パス プロパティのように
- Drink エンティティとツリー内のすべての親の間の関係を複製します ...
助言がありますか?
こんにちは。
私たちのケースは、2 番目の例で示したように、より厳密な階層的アプローチです。また、クエリは製品のリストを取得するためのものであり、1 つだけを取得することは通常ありません。
原産地、ワイナリー、または品種からすべてのワインを取得する必要があります (品種が厳密な階層ツリーの別のノードであると仮定した場合、これは単なる例です)
あなたが言及したように、1つの方法はパスプロパティを含めることができます:
- /origin/{id}/winery/{id}/variety/{id}
次のようなクエリを適用して、さまざまなワインからワインのリストを取得できるようにするには:
wines_query = Wine.all()
wines_query.filter('key_name >','/origin/toscana/winery/latoscana/variety/merlot/')
wines_query.filter('key_name <','/origin/toscana/winery/latoscana/variety/merlot/zzzzzzzz')
または、オリジンから次のようにします。
wines_query = Wine.all()
wines_query.filter('key_name >','/origin/toscana/')
wines_query.filter('key_name <','/origin/toscana/zzzzzz')
ありがとうございました!