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