将所有数据存储区实体放在一个组中的目的是什么?

时间:2016-04-08 10:11:47

标签: google-app-engine data-modeling google-cloud-datastore

我已经开始研究使用Google数据存储区的现有项目,其中对于某些实体类型,每个实体都被分配了相同的祖先。例如:

class BaseModel(ndb.Model):
    @classmethod
    def create(cls, **kwargs):
        return cls(parent=cls.make_key(), **kwargs)
    @classmethod
    def make_key(cls):
        return ndb.Key('Group', cls.key_name())

class Vehicle(BaseModel):
    @classmethod
    def key_name(cls):
        return 'vehicle_group'

所以键最终看起来像这样:

Key(Group, 'vehicle_group', Vehicle, 5068993417183232)

没有“组”或实体“vehicle_group”这样的类型,但在这些文档中没有问题:"note that unlike in a file system, the parent entity need not actually exist"

我从阅读中理解,这可能具有性能优势,因为所有实体都在分布式数据存储中共存。

但是将所有这些实体放在一个组中会在我的脑海中产生问题,因为这个项目可以扩展,每秒一次的写入限制将适用于整个类型。该组似乎没有任何交易原因。

项目中没有人知道为什么它最初是这样做的。我的问题是:

  • 有谁知道这个“xxx_group”单一实体方案的来源 从?
  • 它看起来像是下铺吗?

2 个答案:

答案 0 :(得分:3)

在单个实体组内对许多实体进行分组提供了至少2个我能想到的优势:

  • 在事务内执行(祖先)查询的能力 - 事务中不允许非祖先(或跨组)查询
  • 访问同一事务中的多个实体的能力 - 跨组事务仅限于最多25个实体组

对于某些应用程序,1个写入/秒/组限制可能根本不是可扩展性问题(例如,想一次读取很多类型的应用程序,或者每次写入1次的应用程序)秒绰绰有余。)

至于机械师,(独特的)父母"实体"该组的密钥是ndb.Key('Group', "xxx_group")密钥(其中包含" xxx_group"密钥ID)。相应的"实体"或者它的模型不需要存在(除非需要创建实体本身,看起来并非如此)。父键仅用于建立组"命名空间"在数据存储区中,如果你想要的话。

您可以在Entity Keys documentation的示例中看到某种类似的用途,查看Message使用情况(Message只是一个"父"实体祖先路径,但不是根实体):

  

类修订版(ndb.Model):         message_text = ndb.StringProperty()

ndb.Key('Account', 'sandy@foo.com', 'Message', 123, 'Revision', '1')
ndb.Key('Account', 'sandy@foo.com', 'Message', 123, 'Revision', '2')
ndb.Key('Account', 'larry@foo.com', 'Message', 456, 'Revision', '1')
ndb.Key('Account', 'larry@foo.com', 'Message', 789, 'Revision', '2')
     

...

     

请注意,Message不是模型类。这是因为我们是   使用Message纯粹作为一种方式对Revisions进行分组,而不是存储数据。

答案 1 :(得分:2)

这可能是为了在组内实现强一致性查询。正如你所指出的那样,这种设计有......缺点。

如果这只是参考数据(即Read many write one),可能会减轻一些负面因素,但也会使正面无效(即如果数据不经常更新,则最终一致性不是问题)。