我试图在App Engine中为我的博客建模一个基本的线性评论系统(你可以在http://codeinsider.us看到它)。我的主要对象类是:
用户, 文章, 评论
一位用户会有很多评论,应该能够一目了然地查看他们的评论。
一篇文章会有很多评论,应该一目了然。
一条评论只与一个用户和一篇文章相关联。
我知道如何在标准的关系数据库中构建它 - 比方说,我可能会为评论,用户和文章分别创建表,使用外键将它们绑定在一起,对文章和用户的唯一性限制,以及没有关于评论等没什么特别的。
使用NDB在Python App Engine中建模的最佳方法是什么? ndb.KeyProperty看起来很有趣,StructuredProperty也是如此。我不认为我可以使用StructuredProperty,因为评论可以"属于"用户和文章。但是使用ndb.KeyProperty,似乎keyProperty没有做任何检查或验证逻辑,所以我必须自己实现它。
我能做的另一件事就是放弃,并在代表键和注释的用户和文章中存储巨大的JSON blob。这可能不是一个糟糕的解决方案。
有什么想法吗?
编辑: 这将是高读,低写。我可以在评论(upvotes / downvotes)上增加一些参与度,但即使这样,它也会对阅读产生很大影响。
答案 0 :(得分:4)
我建议您仔细考虑您计划提供哪些功能,因为以某种方式构建模型可能会在未来发生一些变化。
我将按如下方式执行此操作:
首先,假设一些最终的一致性。无论您如何设计,在某些查询中都会有一些最终的一致性。
在文章中创建KeyProperty“所有者”以存储user_key。如果您想在查询单个用户的文章时实现强一致性,那么不要使用“所有者”KeyProperty,只需将user_key作为文章的父级(这将为用户创建一个实体组及其文章,这里很好)。
通过评论,你可以做更多的事情。
如果您预期少于100(取决于文章大小) 数据存储可以更多)每篇文章的评论创建一个评论 文章中的KeyProperty(重复= True)存储所有注释键 然后使用get_multi(强一致性)获取它们。
创建评论并修改文章评论属性 你可能需要一个交易,因为你会想要完成 两个操作或不操作。但是..这两个实体都不在 同一实体组如此:1)使用跨群交易或2)制作 文章的评论的父母(这第二个选项将有一些 后面讨论的后果)评论的意思很简单但是 如前所述,限制为100或更多评论。
使用两个KeyProperties创建一个Comment ndb模型,“owner”和 “文章”。本文将使用查询获取注释。要查询 你最终会有一篇文章中的所有评论 一致性,除非您将文章作为评论的父级 (在这种情况下,当然不要创建文章KeyProperty)。这个 方法允许大量评论。
使用实体组的问题是,例如,如果您允许对注释进行投票,则对每个注释执行单个写操作将阻止受影响的文章的孔实体组中的任何写入。因此,其他用户的创建和投票可能会受到影响。但是,如果您期望很少投票并且实体组保持较小,那么不要真正关心这一点。
如果你想允许评论投票,这可能会变得非常复杂,例如你可能想要每个用户只有一票。这需要额外的关系,以前需要考虑。
我个人更喜欢几乎总是假设最终的一致性。
可能有更多方法,但我喜欢这两种方法。
答案 1 :(得分:1)
高读,低写的场景是GAE的专长,所以这对你的目的来说是件好事。
我利用GAE模型的ancestry feature,因为它可以确保实体组内的事务/原子操作。我想你不需要那么多,但保持静止是件好事。
正确的结构取决于您处理/使用数据的方式。我假设您博客中的典型案例是显示文章的评论,因此,我会将您的评论模型设为您文章模型的子项 - 然后您可以查询某个文章的评论(文章)祖先,这将是辉煌的。
我在评论中包含了作者的KeyProperty,因为它主要用于从我假设的密钥中获取用户。如果要扩展KeyProperty功能,可以这样做。以下是有关如何在db中使KeyProperty behave as ReferenceProperty使用的示例。 (第1点。)