我是google-app-engine和google datastore(bigtable)的新用户,我有些疑惑,这可能是设计所需数据模型的最佳方法。
我需要创建一个层次结构模型,类似于产品目录,每个域都有一些深层子域。目前,产品的结构变化小于读取要求。葡萄酒示例:
所有关系都是不相交和不完整的。此外,按照要求的顺序,我们可能需要存储每种葡萄酒的使用计数器(可能需要交易)
按照文档的顺序,似乎有不同的潜在解决方案:
但是为了获得葡萄酒的预期要求......有时候是按品种,有时是按品种,有时是酒庄......我担心使用这些结构的查询行为(比如关系模型。如果你要求一个家庭的产品...你需要加入产品树中的最终深度限定符,并加入自家庭以来)
创建一些重复的信息可能更好(按照Google团队建议的顺序:操作很昂贵,但存储不是,所以不应该看到重复的内容是主要问题)
其他类似问题的一些回答表明:
有什么建议吗?
嗨,威尔,
我们的案例更像是一种严格的分层方法,正如您在第二个例子中所表达的那样。并且查询用于检索产品列表,只检索一个不常见的。
我们需要从Origin,Winery或Variety中检索所有葡萄酒(如果我们认为该品种是严格分层树的另一个节点,仅仅是一个例子)
一种方法可能是包含路径属性,如您所述:
允许我从应用如下查询的各种葡萄酒中检索葡萄酒列表:
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')
谢谢!
答案 0 :(得分: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)
并且,假设您将葡萄品种作为葡萄酒模型的属性存储,所有特定品种的葡萄酒都如此简单
wines_query = Wine.all().filter('variety =', 'merlot')
这种严格的分层方法的一个可能的缺点是它可以强加给你的URL方案。使用类似于
的层次结构Origin -> Winery -> Wine
您必须知道葡萄酒原产地和酒庄的钥匙名称或ID,才能建立检索该葡萄酒的钥匙。除非你已经获得了葡萄酒钥匙的字符串表示。这基本上迫使您以下列形式之一获得葡萄酒的URL:
/origin/{id}/winery/{id}/wine/{id}
/wine/{opaque and unfriendly datastore key as a string}
(第一个URL当然可以用查询字符串参数替换;重要的是你需要三个不同的信息来识别给定的葡萄酒。)
但是,对我来说,这些URL方案还有其他替代方案。