对不起,如果这个问题太简单了;我只进入了9年级。
我正在尝试了解NoSQL数据库设计。我想设计一个最小化读/写次数的Google数据存储模型。
以下是博客文章的玩具示例以及一对多关系中的评论。哪个更有效 - 将所有注释存储在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...
随意提出与有效表示一对多关系相关的任何其他注意事项,以尽量减少对数据存储区的读/写次数。
感谢。
答案 0 :(得分:13)
我可能错了,但根据我的理解,StructuredProperty只是实体中的一个属性,但具有子属性。
这意味着阅读BlogPost及其所有评论只需要一次阅读。因此,当您渲染页面时,整个页面只需要一个读取操作。
写作也会更便宜。你需要一个读取操作才能获得BlogPost,只要你不更新任何索引属性,它就只能是一个写操作。
您可以在从数据存储中读取实体后自行处理注释排序。
您必须将评论更新/编辑与事务同步,以确保一条评论不会覆盖另一条评论,因为它们都在修改同一个实体。如果每个人都在同时评论和编辑同一篇博客帖子,您可能会遇到无法解决的问题。
在优化成本方面,您将遇到最大实体大小为1MB的墙。这将限制每个博客帖子可以存储的评论数量。
使用KeyProperty将会更加昂贵。
每个评论都需要一次阅读才能获得博文,另外还需要1次查询和1次小型阅读操作。
每个评论都是一个新实体,所以它至少会有4个写操作。您可能希望为排序顺序编制索引,这样最终会花费更多的写操作。
从好的方面来说,每篇博文都会有无限评论,您不必担心同步新评论。您可能需要担心编辑注释的同步,但如果您将编辑限制为创建者,那么这不应该是一个问题。您也不必自己排序。
这是成本与功能之间的权衡。
答案 1 :(得分: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。当然,这取决于您的用例,这是否是一个很好的假设。
答案 2 :(得分:1)
使用重复的StructuredProperty时要注意这一点:
如果值超过100-1000,请勿使用重复属性。 (1000可能已经推动了它。)它们并没有被设计用于此类用途。
请参阅GAE ndb design, performance and use of repeated properties中的Guido答案。
因此,虽然您可能无法使用StructuredProperty达到1 MB实体限制,但您可以轻松达到建议的最大值100-1000。