应用引擎数据存储区中的邮政地址模型,共同属性的结构应该如何?

时间:2012-07-09 14:59:10

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

假设我们拥有基于2个模型的数百万个地址。

  1. Address模型具有纯字符串属性,即使是county等常见属性:

    class Address(ndb.Model):
    
      house_no = ndb.StringProperty()
      street = ndb.StringProperty()
      locality = ndb.StringProperty() # City/town
      county = ndb.StringProperty()
      zipcode = ndb.StringProperty()
    
  2. StructuredAddress模型通过将每个属性定义为KeyProperty来保留更常见的属性作为对其他模型的引用:

    class StructuredAddress(ndb.Model):
    
      house_no = ndb.StringProperty()
      street = ndb.StringProperty()
      locality = ndb.KeyProperty(kind=Locality) # City/town
      county = ndb.KeyProperty(kind=County)
      zipcode = ndb.KeyProperty(kind=Zipcode)
    
  3. 以下是问题:

    • 根据zipcode等常见属性查询哪个模型效率更高?

    • 假设county属性的数量约为50,而zipcode属性的数量约为数百万。鉴于数百万个地址记录,在这种情况下哪个模型会更有效?

    • 在此示例中使用KeyProperty是否意味着更多的阅读操作,并且实际上更高的账单?内置的ndb缓存是否已经避免了这种情况?

2 个答案:

答案 0 :(得分:2)

KeyProperty版本会更昂贵,因为Key占用的字节数比典型的邮政编码或城镇/县名更多。 (每个键重复其指向的全名。)

除了被动存储成本之外,您还需要支付额外的阅读费用来阅读密钥引用的字段。

最后,没有办法直接执行你需要进行这些查询的JOIN(尽管这可能只是一次查询)。

使用密钥购买的唯一方法就是可以更改城镇或县的名称。但这种情况多久发生一次?

答案 1 :(得分:1)

  

根据像zipcode这样的常见属性查询哪个模型更有效?

假设ZipCode类只包含带有邮政编码的String / Int属性,(1)将使用一个RPC完成此查询,(2)将使用两个RPC:

(1)

# Get the first 100 adresses with zipcode 55555
addresses = Address.query().filter('zipcode','55555').fetch(limit=100)

(2)

# Get the key of the zipcode 55555
zip = Zipcode.query().filter('code','55555').get()
# Get the first 100 addresses with the zipcode 55555
addresses = StructuredAddress.query().filter('zipcode',zip.key()).fetch(limit=100)

所以这里(1)是优越的。

  

假设国家/地区属性数量约为50,而邮政编码属性数量约为数百万。鉴于数百万个地址记录,在这种情况下哪个模型会更有效?

再次假设只有一个字符串与一个邮政编码相关联,并且通过效率,您正在谈论存储效率:(1)您只需存储数百万个地址,(2)您必须存储数以百万计的地址和数百万个zipcodes(1)将更有效率。

再次,(1)将是优越的。

  

在这个例子中使用KeyProperty是否意味着更多的阅读操作,并且有效地提高了账单?内置的ndb缓存是否已经避免了这种情况?

简而言之,是的,正如第一个问题的答案所证明的那样。实际上,您唯一想要使用KeyProperty的时候是有多个字段存储在参考模型中。