16

对不起,如果这个问题太简单了;我才上九年级。

我正在尝试了解 NoSQL 数据库设计。我想设计一个谷歌数据存储模型,最大限度地减少读/写次数。

这是一个玩具示例,用于一对多关系中的博客文章和评论。哪个更有效 - 将所有评论存储在 StructuredProperty 中或在 Comment 模型中使用 KeyProperty?

同样,目标是尽量减少对数据存储的读/写次数。您可以做出以下假设:

  • 评论将不会独立于其各自的博客文章而被检索。(我怀疑这使得 StructuredProperty 最可取。)
  • 评论需要按日期、评级、作者等进行排序。(无法索引数据存储中的子属性,所以这可能会影响性能?)
  • 博客文章和评论都可以在创建后进行编辑(甚至删除)。

使用结构化属性:

from google.appengine.ext import ndb

class Comment(ndb.Model):
    various properties...

class BlogPost(ndb.Model):
    comments = ndb.StructuredProperty(Comment, repeated=True)
    various other properties...

使用 KeyProperty:

from google.appengine.ext import ndb

class BlogPost(ndb.Model):
    various properties...

class Comment(ndb.Model):
    blogPost = ndb.KeyProperty(kind=BlogPost)
    various other properties...

随意提出与有效表示一对多关系有关的任何其他注意事项,以最大限度地减少对数据存储的读/写次数。

谢谢。

4

3 回答 3

14

我可能是错的,但据我了解,StructuredProperty 只是实体内的一个属性,但具有子属性。

这意味着阅读 BlogPost 及其所有评论只需阅读一次。因此,当您渲染页面时,您只需要一个读取整个页面的操作。

写入也会更便宜。您需要一个读取操作来获取 BlogPost,只要您不更新任何索引属性,它就只是一个写入操作。

从数据存储中读取实体后,您可以自行处理评论排序。

您必须将评论更新/编辑与事务同步,以确保一条评论不会覆盖另一条评论,因为它们都在修改同一个实体。如果每个人同时评论和编辑同一篇博文,您可能会遇到无法解决的问题。

但是,在优化成本时,您将遇到最大实体大小为 1MB 的墙。这将限制您可以在每篇博文中存储的评论数量。

使用 KeyProperty 会贵很多。

您需要阅读一次才能获得博客文章,外加 1 次查询以及每条评论的 1 次小型阅读操作。

每条评论都是一个新实体,因此至少有 4 个写操作。您可能希望索引排序顺序,因此最终会花费更多的写入操作。

从好的方面来说,每篇博文都有无限的评论,您不必担心同步新评论。您可能需要担心编辑评论的同步,但如果您将编辑限制为创建者,那应该不是问题。您也不必自己进行排序。

这是成本与功​​能的权衡。

于 2012-07-31T21:53:37.003 回答
3

关于什么:

from google.appengine.ext import ndb

class Comment(ndb.Model):
    various properties...

class BlogPost(ndb.Model):
    comments = ndb.KeyProperty(Comment, repeated=True)
    various other properties...

这样,您可以在每篇博文中存储多达 5000 条评论(重复属性的最大数量),而与每篇博文的大小无关。您不需要查询来获取博客以获取评论,您只需执行ndb.get_multi(blog_post.comments). 而对于这个操作,可以尝试依赖ndb的memcache。当然,这是否是一个好的假设取决于您的用例。

于 2013-05-24T10:45:48.827 回答
1

使用重复的 StructuredProperty 时请注意此警告:

如果您有超过 100-1000 个值,请不要使用重复的属性。(1000 可能已经在推动它了。)它们不是为这种用途而设计的。

请参阅 Guido 在GAE ndb 设计、性能和重复属性使用中的回答。

因此,虽然您可能无法使用 StructuredProperty 达到 1 MB 实体限制,但您可以轻松达到建议的最大值 100-1000。

于 2015-10-01T21:38:22.453 回答