我想知道是否有人可以提供一些有关构建数据模型以实现下述简单系统的有效方法的概念建议。对于以非关系方式思考并且想要尝试避免任何明显的陷阱,我有点新鲜。我的理解是,基本原则是“存储便宜,不要担心数据重复”,就像在规范化的RDBMS中一样。
我想建模的是:
一篇可以给出0-n标签的博客文章。许多博客文章可以共享相同的标签。检索数据时,希望允许检索与标记匹配的所有文章。在许多方面与stackoverflow中采用的方法非常相似。
我的正常心态是在标签和博客文章之间建立多对多的关系。但是,我在GAE的背景下考虑这将是昂贵的,虽然我已经看到它的例子。
也许使用包含每个标记的ListProperty作为文章实体的一部分,并使用第二个数据模型来跟踪添加和删除标记的标记?这种方式不需要任何关系,ListProperty仍然允许查询,其中任何列表元素匹配将返回结果。
关于在GAE上实现此方法的最有效方法的任何建议?
答案 0 :(得分:7)
感谢你们两位的建议。我已经实现了(第一次迭代)如下。不确定这是否是最佳方法,但它正在发挥作用。
A类=文章。有一个StringListProperty,可以在它的列表元素上查询
B类=标签。每个标签一个实体,还保留使用每个标签的文章总数的运行计数。
对A的数据修改伴随着对B的维护工作。在重读环境中,考虑预先计算是一种好方法。
答案 1 :(得分:2)
预先计算的计数是不仅实际,而且还必须因为count()函数返回最大值1000 。如果写入争用可能是个问题,请务必查看分片计数器示例。
http://code.google.com/appengine/articles/sharding_counters.html
答案 2 :(得分:1)
多对多听起来很合理。也许你应该先试试看它是否真的很贵。
关于G.A.E.的好事它会告诉你何时使用太多周期。分析免费!
答案 3 :(得分:1)
一种可能的方法是使用Expando
,您可以在其中添加以下标记:
setattr(entity, 'tag_'+tag_name, True)
然后,您可以使用以下标记查询所有实体:
def get_all_with_tag(model_class, tag):
return model_class.all().filter('tag_%s =' % tag, True)
当然,你必须清理你的标签才能成为合适的Python标识符。我没试过这个,所以我不确定它是否真的是一个很好的解决方案。