5

我是 google-app-engine 和 google datastore (bigtable) 的新手,我有一些疑问,其中的顺序可能是设计所需数据模型的最佳方法。

我需要创建一个层次模型,比如产品目录,每个域都有一些深入的子域。目前,产品结构的变化小于读取要求。葡萄酒示例:

  • 原产地(托斯卡纳、普里奥拉特、阿尔萨斯)
  • 酒厂(只属于一个产地)
  • 酒(只属于一家酒厂)

所有的关系都是不相交和不完整的。此外,按照要求的顺序,我们可能需要为每种葡萄酒存储使用计数器(可能需要交易)

按照文档的顺序,似乎有不同的潜在解决方案:

  • 祖宗管理。使用父关系和事务
  • 伪祖先管理。使用 db.ListProperty(db.Key) 模拟祖先
  • 参考属性。明确指定类之间的关系

但是为了获得葡萄酒的预期请求......有时按品种,有时按原产地,有时按酒厂......我担心使用这些结构的查询的行为(比如关系模型中的多个连接。如果你要求一个家族的产品...你需要加入产品树中的最终深度限定符并加入家族)

也许最好创建一些重复的信息(按照google团队建议的顺序:操作很昂贵,但存储不是,所以重复的内容不应该是主要问题)

其他类似问题的一些回答表明:

  • 将所有父 ID 存储为字符串中的层次结构......就像路径属性
  • 复制 Drink 实体与树中所有父母之间的关系...

有什么建议么?


嗨,威尔,

正如您在第二个示例中所表示的那样,我们的案例更像是一种严格的分层方法。并且查询是用于检索产品列表,仅检索一个是不常见的。

我们需要从 Origin、Winery 或 Variety 中检索所有葡萄酒(如果我们假设品种是严格层次树的另一个节点,这只是一个示例)

正如您所提到的,一种方法可能是包含路径属性:

  • /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')

这种严格的分层方法的一个可能缺点是它可以强加给您的那种 URL 方案。具有看起来像的层次结构

Origin -> Winery -> Wine

you must know the key name or ID of a wine's origin and winery in order to build a key to retrieve that wine. Unless you've already got the string representation of a wine's key. This basically forces you to have URLs for wines in one of the following forms:

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

(The first URL could of course be replaced with querystring parameters; the important part is that you need three different pieces of information to identify a given wine.)

Maybe there are other alternatives to these URL schemes that have not occurred to me, though.

于 2010-09-01T17:20:43.760 回答