我最近一直在玩谷歌应用引擎及其数据存储,并使用引用属性创建了数据模型和关系。
但是我不清楚数据存储区中祖先的概念。他们的目的是什么,我为什么要使用它们?它们如何与数据存储区实体的引用属性相关?
答案 0 :(得分:17)
实体组/祖先的另一个好处是创建一致性强的岛屿(而不是最终的一致性)。
例如,您可以拥有一个项目及其任务。如果没有祖先,您可以“关闭”任务,返回项目的任务列表屏幕,并查看打开的任务。由于最终的一致性,您刚刚关闭的任务仍然可能会显示出来。可能已针对尚未复制更新的服务器解析了该查询。
然而,对于祖先,你会获得很强的一致性。因此,不是从任务到项目的简单外键,而是将项目作为项目任务的祖先。现在,在查询任务时,通过提供项目密钥使其成为祖先查询。结果将非常一致,您刚关闭的任务将不会成为结果的一部分。
答案 1 :(得分:9)
通常使用的例子是作者和他们的书。
每本书都作为一个单独的实体存储在数据存储区中,并将其名称和作者存储为模型中的字段。
如果您想了解单个作者的所有书籍,您可以运行查询
book.author == desired_author
但是对于祖先,你也可以保存每本书并设置一个模型(一个新的作者模型)作为它的父(它的祖先)。
所以现在你可以简单地说“给我看这本作者作为父母的所有书籍”。
或者更确切地说“告诉我这个祖先的所有孩子”,并返回该作者的所有书籍。
在这个例子中似乎没有用,但是如果你想象的是“作者”而不是“用户”,而不是“书”你有“留言板信息”和成千上万的消息,突然变成非常方便能够找到用户的所有消息(例如,显示我自己的消息)。
https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_ancestor
ancestor (ancestor)
Adds an ancestor filter to the query. The query will return only entities with the specified ancestor.
找到我期望的每条记录的成本也有好处。
答案 2 :(得分:2)
提供祖先使您的(新)实体成为与提供的祖先相同的实体组的一部分。因此,具有共同根实体作为祖先的所有实体都存储在同一数据存储节点中,该“位置”允许在事务内对所有这些实体(在同一实体组中)执行许多动作。然后对于包含祖先查询的任何查询(例如只返回子节点作为公共根实体的实体),这些操作似乎同时(原子地)或根本不发生。
价: http://www2.mta.ac.il/~kirsh/download/MTA%20NoSQL%20Seminar/Lectures/GAE.pdf