我一直在使用Google App Engine,而且我的一些数据查询运行速度很慢。我已经读过,设计一个App Engine数据存储区与使用SQL数据库是一种不同的心态,我不确定我是这样做的最佳方式。我有两个问题要尝试走上正轨:
具体来说:
我有Foo
类型和UserFoo
类型。每个UserFoo
都是对应Foo
的“实例”,并保存特定于该实例的数据。我的Foo
类型具有fooCode
属性,这是一个唯一标识符,我使用UserFoo
属性将每个Foo
映射到每个fooCode
。然后我使用如下代码对每个Foo进行操作:
foos = Foo.all().filter('bar =', bar)
for foo in foos:
userFoo = UserFoo.all().filter('userKey =', user).filter('fooCode =', foo.fooCode)
注意:我在引用键上使用fooCode
,以便我们可以轻松删除并重新添加新的Foo
,而不必重新映射所有相应的UserFoo
s
一般情况:
设计GAE数据存储表的典型方法和使用它们的最佳实践是什么?
答案 0 :(得分:1)
一般情况:
尽可能地反规范化。
通过密钥引用实体 只要有可能;这是最快的 从数据存储区中获取数据的方法。
具体来说,如果您使用ReferenceProperty来建立关系而不是进入过滤器的代码,那么您的性能可能会大幅提升。我猜测,查询UserFoo的Foo比删除和重新映射Foo更常见,是吗?在这种情况下,实用和数据存储方面要做的是使用引用属性。
此外,如果可以将Foo-UserFoo关系非规范化为单个实体,则无需完全删除整个查询系列。
答案 1 :(得分:1)
这是staircase of gets反模式。解决方案是ReferenceProperty pre-fetching。
遗憾的是你决定不使用ReferenceProperty。我建议你重新考虑这个选择。
注意:我正在使用fooCode 参考键使我们可以轻松 删除并重新添加新的Foo而不是 必须重新映射所有 相应的UserFoos。
请记住,实体键只是其路径的编码表示:实体及其任何祖先的种类和名称或ID。如果您删除然后重新创建Foo
,则只有给出不同的名称或ID才会有不同的密钥。如果您有某种方式为旧实体和新实体提供相同的fooCode
,您可以轻松地使用fooCode
作为密钥名称,这将允许删除然后重新添加{{1保留原始密钥。
答案 2 :(得分:1)
我建议进行以下更改: