我有四种主要类型:帐户,公司,服务和地址。我希望在公司和服务实体之间共享地址实体。
挑战: 公司和服务实体可能具有不同的地址;毕竟,公司的地址不一定是获得服务的地方。服务可能有许多地址,因为公司可能会设立不同的特许经营/出口,可以获得其服务。
我想以这样的方式对数据建模,即公司或服务实体或两者都可以引用地址。我尝试了这两种方法:
我们假设这是地址模型:
class Address(ndb.Model):
street = ndb.StringProperty(required=True)
city = ndb.StringProperty(required=True)
country = ndb.StringProperty(required=True)
方法1 :存储服务或公司内的地址密钥列表
class Service(ndb.Model):
title = ndb.StringProperty(required=True)
addresses = ndb.KeyProperty(repeated=True)
class Company(ndb.Model):
name = ndb.StringProperty(required=True)
addresses = ndb.KeyProperty(repeated=True)
问题:对于服务或公司的每个页面视图,我需要执行其他查询以获取其各自的地址。随着我们的实体数量的增长,这会成为一个非常昂贵的问题。
方法2 :创建一个AddressMapping实体,形成两个实体之间的关系:
class Service(ndb.Model):
title = ndb.StringProperty(required=True)
addresses = ndb.KeyProperty(repeated=True)
class AddressMapping(ndb.Model):
entity = ndb.StringProperty(required=True) # service or company
address = ndb.KeyProperty(repeated=True)
问题:如果服务被禁用/删除/修改,我们需要删除/修改所有附带的AddressMapping实体,否则它们将被孤立。查看页面时仍需要其他查询。这看起来也很昂贵。
这是我提出的两种方法;他们都看起来很糟糕。关于如何改进这个的任何想法?
答案 0 :(得分:1)
如果您在公司和服务模型中存储地址密钥,则不需要“其他查询来获取它们” - 您只需get
所有地址实体即可。这很快又便宜。
答案 1 :(得分:0)
这是数据存储区的一个非常标准的问题。解决方案是非规范化。通过允许重复,您可以将问题分解为一对多关系。因此,在您的示例中:允许Address
重复,并让每个Address
都有父Company
或Service
。或者将您的Address
实体拆分为两个(ServiceAddress
,CompanyAddress
)。
现在修改Service
或Company
时,您可以对地址执行简单的祖先查询,您只能获得相应的地址。
此方法假设您不会每秒更新Address
(或您拥有的任何其他实体),因为您将遇到每秒1次写入和其他实体组。