最好先举个例子来说明这种情况。假设我们有一个User
类,它应该有一个Post
.
第一个想法是在User
类中创建这个列表,但是分析用例我们发现大多数时候我们想要检索没有帖子的用户并检索没有用户的帖子。但是,我们需要用户 ID 来检索帖子。因此,创建数据模型的另一种方法是没有关联,而是按ID创建Post
索引。User
在成本方面,这两种实现方式的优缺点是什么?
最好先举个例子来说明这种情况。假设我们有一个User
类,它应该有一个Post
.
第一个想法是在User
类中创建这个列表,但是分析用例我们发现大多数时候我们想要检索没有帖子的用户并检索没有用户的帖子。但是,我们需要用户 ID 来检索帖子。因此,创建数据模型的另一种方法是没有关联,而是按ID创建Post
索引。User
在成本方面,这两种实现方式的优缺点是什么?
我之前的回答是假设您实际上是在 User 实体中存储 Post 对象列表。听起来您在询问 User 和 Post 是否都是实体,并且 User 存储了 Posts 的键列表。
第一种情况(具有 Post 实体的键列表的用户)的主要好处是它使您能够以一致的方式获取 Posts。获取 User 对象后,您可以读取 POSTS 列表并单独获取它们。数据存储区按密钥获取操作是一致的。根据您发出 get 操作的方式,这可能比查询慢。(即,如果您只使用 for 循环)。
可能还有一个非常小的其他好处,只要您不在用户中索引您的帖子列表,您就可以通过这种方式相对便宜地更新您的用户。举个极端的例子,如果你的用户一次添加了 5 个帖子,你可以将它们全部添加到列表中,然后通过一次写入操作写入用户一次。这并不是真的那么好,因为无论如何您可能都必须编写您的 Post 实体,但它是每个实体少一个索引写入操作。
用户实体的大小仍然有限制,因此您的列表将有最大限制。每个实体的索引条目数也有最大值,所以如果你索引列表,这可能是一个限制(但这也会使用户实体的编写成本更高)。
从阅读的角度来看,第一种情况不是最佳的。
从读取的角度来看,第二种情况效果更好,如果您有 User id,则更容易获取 Posts,但在编写 Post 时您有索引写入操作。如果你不经常写帖子,这会更好。请注意,查询实际上是一致的。
请参阅计费页面,特别是有关数据存储操作的部分:
https://developers.google.com/appengine/docs/billing
每个实体的数据存储读取成本都会增加。每个索引属性的数据存储写入成本都会增加。
第一种方法会便宜得多,因为它只在一个用户实体上运行,并且不需要索引。
但是,成本可能不是您唯一的决定因素。每个实体限制为 1MB,因此如果您将帖子存储在您的用户实体中,您可能会碰壁。读取/写入实体的时间也取决于大小,因此大型实体将需要更长的时间来读取/写入。