5

私は 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')

ありがとうございました!

4

1 に答える 1

1

質問に記載されているものに加えて、どのような種類のクエリを実行する必要があるかはわかりませんが、明示的な祖先階層にデータを保存すると、質問したものが簡単に落ちてしまいます。

たとえば、特定の産地からすべてのワインを取得するには:

origin_key = db.Key.from_path('Origin', 123)
wines_query = db.Query(Wine).ancestor(origin_key)

または、特定のワイナリーからすべてのワインを取得するには:

origin_key = db.Key.from_path('Origin', 123)
winery_key = db.Key.from_path('Winery', 456, parent=origin_key)
wines_query = db.Query(Wine).ancestor(winery_key)

Wine モデルのプロパティとして品種を保存すると仮定すると、特定の品種のすべてのワインは次のように単純です。

wines_query = Wine.all().filter('variety =', 'merlot')

この厳密な階層的アプローチの考えられる欠点の 1 つは、それが課す可能性のある URL スキームの種類です。次のような階層で

Origin -> Winery -> Wine

ワインを取得するためのキーを作成するには、ワインの原産地ワイナリーのキー名または ID を知っている必要があります。ワインのキーの文字列表現を既に取得していない限り。これにより、基本的に次のいずれかの形式でワインの URL を取得する必要があります。

  • /origin/{id}/winery/{id}/wine/{id}
  • /wine/{opaque and unfriendly datastore key as a string}

(もちろん、最初の URL はクエリ文字列パラメーターに置き換えることができます。重要な部分は、特定のワインを識別するために 3 つの異なる情報が必要だということです。)

ただし、これらの URL スキームに代わるものは他にもあるかもしれませんが、私には思い浮かびませんでした。

于 2010-09-01T17:20:43.760 に答える