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

What would be the purpose of putting all datastore entities in a single group?

我已经开始处理一个使用 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)

没有 'Group' 或实体 'vehicle_group' 这样的类型,但在这些文档中没关系:"note that unlike in a file system, the parent entity need not actually exist".

我从阅读中了解到,这可能具有性能优势,因为一种类型的所有实体都位于分布式数据存储区中。

但是在我看来,将所有这些实体放在一个组中会随着项目的扩展而产生问题,并且每秒一次的写入限制将适用于整个类型。该小组似乎没有任何交易原因。

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

将多个实体分组到一个实体组中至少有 2 个我能想到的优势:

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

1 write/second/group 限制 可能 对于某些应用程序来说根本不是可扩展性问题(例如,想想写一次读取很多类型的应用程序,或应用程序每秒 1 次写入就足够了)。

至于机制,组的(唯一)父 "entity" 密钥是 ndb.Key('Group', "xxx_group") 密钥(具有 "xxx_group" 密钥 ID)。相应的 "entity" 或其模型不需要存在(除非需要创建实体本身,但似乎并非如此)。如果需要,父键仅用于在数据存储中建立组的 "namespace"。

您可以在 Entity Keys documentation 的示例中看到某种类似的用法,请查看 Message 用法(除了 Message 只是一个 "parent" 实体祖先路径,但不是根实体):

class Revision(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')

...

Notice that Message is not a model class. This is because we are using Message purely as a way to group Revisions, not to store data.

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

如果这仅仅是参考数据(即一次读取多次写入)可能会减轻一些负面影响,但也主要使正面无效(即如果数据不经常更新,最终一致性不是问题)。