在Google App Engine Datastore中存储分层数据?

24

有人能说明如何在Google App Engine Datastore中存储和轻松查询分层数据吗?

3个回答

21
最佳选项取决于您的需求。以下是一些解决方案(假设您正在使用Python,因为您没有特别说明):
  1. 如果您需要对整个树进行事务更新,并且每棵树的持续更新不超过约1QPS,则可以使用内置的分层存储支持。在创建实体时,您可以传递“parent”属性以指定父实体或键,在查询时,您可以使用.ancestor()方法(或在GQL中使用“ANCESTOR IS”)来检索给定实体的所有后代。
  2. 如果您不需要事务更新,则可以复制实体组的功能而避免争用问题(和事务安全性):将名为“ancestors”的db.ListProperty(db.Key)添加到您的模型中,并使用要插入对象的祖先列表填充它。然后,您可以轻松地通过MyModel.all().filter('ancestors =', parent_key)检索从给定祖先下降的所有内容。
  3. 如果您不需要事务,而且只关心实体的直接子项(而不是所有后代),则可以使用上面概述的方法,但是不要使用ListProperty,而是使用对父实体的引用属性。这称为“邻接列表”。
还有其他可用的方法,但这三种应该涵盖最常见的情况。

点(2)回答了我的问题!谢谢。 - MathOldTimer
2
看起来(2)和(1)做的事情一样,但是(1)会更便宜。我想一个关键字列表在存储成本方面相当昂贵,这只会随着树的深入而变得更糟。此外,(1)不会导致很好的局部性吗? - Paul Biggar
3
内置的祖先支持使用与 2 相同的技术 - 它在内部存储祖先列表。2 的优点是您没有交易速率限制。位置不是问题。 - Nick Johnson
对于(3),您很可能希望使用SelfReferenceProperty类型,因为父级很可能与自身类型相同。 - Ben Bederson

3
好的,您应该尽可能使数据保持线性。如果您需要快速查询数据的树形结构,则可以将其存储在数据库中(如果您的数据允许)或以JSON编码方式存储。否则,您就必须生成可以用于快速查询树形结构一部分的树索引。不过,我不确定谷歌应用引擎在更新这些索引时的表现如何。
谈到谷歌应用引擎,您的主要关注点应该是减少查询次数,以及使您的查询返回的行数尽量少。操作很昂贵,但存储并不昂贵,因此冗余不应被视为坏事。
这里有一些我通过谷歌搜索找到的相关思路(虽然是针对MySQL的,但您可以从中得到一般想法):管理MySQL中的分层数据
啊,这里还有一篇针对谷歌应用引擎的讨论:建模分层数据

0

一种方法是使用模型的parent属性。然后可以利用query.ancestor()和model.parent()函数。

我想这取决于您想对这些数据进行哪种操作,这将决定如何最好地表示它。


2
这不是一个好主意。只有在需要事务时才应该使用实体组。根据文档:“仅在需要事务时使用实体组。对于实体之间的其他关系,请使用ReferenceProperty属性和Key值,这些可以在查询中使用。” - Blixt
还要记住:实体的父级不能被更改,但是ReferenceProperty可以! - Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接