假设我们拥有基于2个模型的数百万个地址。
Address
模型具有纯字符串属性,即使是county
等常见属性:
class Address(ndb.Model):
house_no = ndb.StringProperty()
street = ndb.StringProperty()
locality = ndb.StringProperty() # City/town
county = ndb.StringProperty()
zipcode = ndb.StringProperty()
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)
以下是问题:
根据zipcode
等常见属性查询哪个模型效率更高?
假设county
属性的数量约为50,而zipcode
属性的数量约为数百万。鉴于数百万个地址记录,在这种情况下哪个模型会更有效?
在此示例中使用KeyProperty
是否意味着更多的阅读操作,并且实际上更高的账单?内置的ndb缓存是否已经避免了这种情况?
答案 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的时候是有多个字段存储在参考模型中。