在Google应用引擎数据存储区中给出以下entity
,是否最好在reportingIds
上定义索引或定义仅包含personId
和reportingIds
字段的单独实体?
根据我理解的文档,定义索引会导致数据存储配额的操作数增加。
以下是GAE Go中的实体。我的代码需要经常扫描Person实体。它需要将其扫描限制为至少有1个报告人的Person实体。我看到了两种方法。
Query
上定义索引。 PersonWithReporters
中的所有实体,而不需要构造任何索引/查询。我可以使用Key进行迭代,而Key始终保证拥有最新数据。考虑到数据存储区操作计入配额限制,不确定哪种方法是有益的。
type Person struct {
Id string //unique person id
//many other personal details, his personal settings etc
reportingIds []string //ids of the Person this guy manages
}
type PersonWithReporters struct {
Id string //Person managing reportees
reportingIds []string //ids of the Person this guy manages
}
答案 0 :(得分:1)
除非Go中的AppEngine数据存储与它在Java或Python中的工作方式非常不同,否则您无法本机索引数组 - 因此选项1是不可能的,选项2也是如此。
我建议选项三,即定义
type PersonWithReporters {
Id string // concatenate(managing_Person_id, separator, reporter_Person_id) to avoid id collisions
reportingId string; // indexed
managingId string; // probably indexed as well
}
您将创建多个这些实体,而不是具有数组的单个实体。您还要在reportingId上添加索引。现在,您可以在此实体上创建过滤器查询,并且应该能够检索所需的信息。
我会更担心性能,而不是太多关于配额限制,它们非常高。只需实施它,看看它是如何工作的,以及配额是否是您的主要关注点。
答案 1 :(得分:1)
具有单独实体的方法为您提供了两个优势。
正如您已经提到的,您不需要索引/查询所有Person实体。
每当一个人获得一个新的报告人时,您将创建一个新实体,这可能比更新具有许多其他属性的Person实体便宜得多,其中一些属性可能被编入索引。
您使用单独实体的方法也不理想。当您使用多个值索引属性时,数据存储区会为每个值创建一个索引条目。因此,当您向此实体添加报告人员编号3时,您必须更新3个索引条目而不是1。
您可以通过创建没有属性的Reporter实体来进一步优化数据模型!每次添加新的报告人员时,您都会创建此Reporter实体,其ID设置为报告人员的ID,并使其成为代表此报告人所报告的人员的Person实体的子实体。
现在,当您需要通过向其报告的所有人进行迭代时,您可以对此Reporter实体运行简单查询 - 无过滤器。这个查询可以设置为仅限密钥(无论如何,这个实体中只有一个密钥,但是只有密钥的查询被区别对待 - 它们基本上是免费的。)
对于此查询返回的每个实体,您都会检索其密钥,此密钥包含一个ID(一个报告人的ID)和一个父密钥,其中包含此报告者向其报告的人员的ID。