谷歌应用引擎博客标签系统的数据建模建议

8
我想请教一下如何高效地构建数据模型来实现以下简单系统。我对非关系型思维还比较陌生,希望能避免明显的陷阱。据我所知,一个基本原则是“存储便宜,不要担心数据重复”,这与规范化的关系型数据库管理系统有所不同。
我想建立的模型是:
一篇博客文章可以被赋予0至n个标签。许多博客文章可以共享相同的标签。在检索数据时,希望能够检索与标签匹配的所有文章。在许多方面,这与stackoverflow采取的方法非常相似。
我的正常思维方式是在标签和博客文章之间创建多对多关系。然而,在GAE的上下文中,我认为这可能会很昂贵,尽管我已经看到了一些例子。
也许可以使用ListProperty将每个标签作为文章实体的一部分,并使用第二个数据模型来跟踪添加和删除的标签?这样就不需要任何关系,而ListProperty仍然允许查询任何匹配列表元素的结果。
您对在GAE上最有效的方法有什么建议吗?
4个回答

7
感谢你们两位的建议。我已经实现了第一次迭代,具体如下。不确定这是否是最佳方法,但它能够正常工作。
A类 = 文章。拥有一个StringListProperty属性,可以对其列表元素进行查询。
B类 = 标签。每个标签都有一个实体,并保持着使用该标签的文章总数的统计信息。
对A进行的数据修改需要伴随B的维护工作。在读取密集型环境中,预先计算计数是一个不错的方法。

正是我打算建议的方法,只是我没有时间。 :) - Nick Johnson

2

在最新版本的 GAE SDK 中,count() 函数没有最大限制:http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_count - Pawel Markowski

1

多对多听起来很合理。也许你应该先尝试一下,看看它是否真的很昂贵。

G.A.E. 的好处是它会告诉你何时使用了太多的循环。免费进行性能分析!


我也考虑过多对多,但是即使在谷歌的文档中也警告说除非必要情况下不要使用。关于性能分析的建议很好,我想我会尝试使用不同的方法运行一些测试,并在这里报告结果。 - Matty

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标识符。我没有尝试过这个,所以我不确定它是否真的是一个好的解决方案。


1
如果标签名称不需要为英语,会怎么样呢? - Eran Kampf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接