我是 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')
谢谢!