NDB数据存储区创建层次结构而不是索引模型属性

时间:2013-12-16 00:45:25

标签: google-app-engine app-engine-ndb

我想创建一个像这样的分层数据库结构: 州  市   地址

其中ndb模型如下所示

class address(ndb.model):
    housenumber = ndb.stringProperty()
    street = ndb.stringProperty()

在我的代码中我创建了像这样的实体

itemkey = address()
itemkey.housenumber = '1003'
itemkey.street = 'foobar'

现在如何创建我想要的层次结构?文档没有显示任何示例。我的理由是,如果我建立了祖先(城市和州),我的查询会更快,而不是将它们作为索引属性放在ndb模型类中。我是对的吗?

1 个答案:

答案 0 :(得分:1)

您可以使用祖先(在键中)或KeyProperties来创建层次结构。您选择哪种方式在很大程度上取决于您使用数据的方式。如果树/层次结构在写入时很重,则单个大型实体组将限制您的写入吞吐量。由祖先组成的层次结构无法更改(即,您无法重新设置事物),因此如果您想重新排列事物,则必须重新编写所有内容。使用KeyProperties指向父级或重复属性以指向子级意味着只有小型更新来移动实体。

在你的例子中,祖先heirarchy可能会起作用,因为门牌号码和街道变化不大。但是如果你添加了所有者/人,你可能会想要使用KeyProperties而不是人们搬家等......

使用KeyProperties列表作为子项运行树很快,因为您只需要使用get()而不是查询。当然,这种方法不适用于大量直系儿童。

如果每个孩子都有KeyProperty持有它的直接父母,那么你可以查询所有直接孩子,缺点是你无法通过单个查询查询所有孩子,无论深度如何。

寻找孩子的祖先查询的缺点是,除非您存储可用于过滤子深度的其他详细信息,否则无论深度如何,您都将获得所有孩子。

正如您所看到的,所有潜在的方法都有自己的优点和缺点。

我建议您设计一个niave模型,查看您的用例和数据访问/操作要求,以确定您需要使用的具体方法。

我使用heirarchies作为CMS,并且不使用祖先,因为我希望能够移动东西(子树)。在另一个项目(教育提供者 - 课程 - 单位层次)中,我们使用祖先,因为这个结构是固定的,并且沿着层次结构的每一步都是不同的类型。因此,限制查询中的孩子很容易。

就您的示例而言,如果您想使用城市/州等的传感器,您可以执行以下操作:

class State(ndb.Model):
  pass

class City(ndb.Model):
  pass

class address(ndb.model):
  housenumber = ndb.stringProperty()
  street = ndb.stringProperty()

state = State(key_name="Western Australia")
state.put()

city = City(ancestor=state.key, key_name="Perth")
city.put()


itemkey = address(ancestor=city.key)
itemkey.housenumber = '1003'
itemkey.street = 'foobar'