我最近一直在玩谷歌应用引擎及其数据存储,并使用引用属性创建了一个数据模型和关系。
但是,我不清楚数据存储的祖先的概念。它们的目的是什么,我为什么要使用它们?它们与数据存储实体的引用属性有何关系?
我最近一直在玩谷歌应用引擎及其数据存储,并使用引用属性创建了一个数据模型和关系。
但是,我不清楚数据存储的祖先的概念。它们的目的是什么,我为什么要使用它们?它们与数据存储实体的引用属性有何关系?
实体组/祖先的另一个好处是创建高度一致性的孤岛(与最终一致性相反)。
例如,您可以有一个项目及其任务。如果没有祖先,您可以“关闭”任务,返回项目的任务列表屏幕,然后查询打开的任务。由于最终的一致性,您刚刚关闭的任务仍然会显示。查询可能已针对尚未复制更新的服务器解决。
但是,对于祖先,您可以获得很强的一致性。因此,您将项目设置为项目任务的祖先,而不是从任务到项目的简单外键。现在,在查询任务时,您还可以通过提供项目键使其成为祖先查询。结果将是高度一致的,您刚刚关闭的任务将永远不会成为结果的一部分。
通常使用的例子是作者和他们的书。
每本书都作为单独的实体存储在数据存储中,其名称和作者存储为模型中的字段。
如果你想知道一个作者的所有书,你可以运行一个查询,这样
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.
查找我期望的每条记录的成本也有好处。
提供祖先会使您的(新)实体成为与提供的祖先相同的实体组的一部分。因此,具有共同根实体作为祖先的所有实体都存储在同一数据存储节点中,此“位置”允许在事务中对所有这些实体(在同一实体组中)执行大量操作。然后对于包含祖先查询的任何查询(例如仅返回作为公共根实体的子实体的实体),这些操作将似乎同时(原子地)发生或根本不发生。
参考: http ://www2.mta.ac.il/~kirsh/download/MTA%20NoSQL%20Seminar/Lectures/GAE.pdf