我正在努力更好地理解GAE NDB docs
中描述的深层次结构的含义“例如,”属于“所有者的邮件的修订版可能有一个看起来像”
的密钥rev_key = ndb.Key('Account', 'Sandy', 'Message', 'greeting', 'Revision', '2')
我认为这意味着如果我Revision(parent=rev_key).put()
那么我将在Revision = 2级别拥有一个实体组,这意味着祖先查询ancestor=rev_key
将具有强一致性并写入{{1}将被限制为1 /秒。
但层次结构的进一步影响是什么?
例如,说我有
parent=rev_key
写入速度是否限制在rev_key_B = ndb.Key('Account', 'Sandy', 'Message', 'greeting', 'Revision', '3')
级别的1 /秒,或者因为它们共享父级的父级,即rev_key_B
,所以写入速度限制在祖先路径上甚至更高,最终到整个实体组一直到ndb.Key('Account', 'Sandy', 'Message', 'greeting')
?
同样的问题:强烈的一致性。 ndb.Key('Account', 'Sandy')
会有很强的一致性吗?
答案 0 :(得分:1)
让我们看看
rev_key = ndb.Key('Account', 'Sandy', 'Message', 'greeting', 'Revision', '2')
表示每个实体在实体路径后都具有很强的一致性。所以你是对的。
让我们看看它的实际效果:创建实体
account_sandy = Account.get_or_insert('Sandy')
sandy_message = Message.get_or_insert('greeting', parent=account_sandy.key)
sandy_message_rev = Revision.get_or_insert('2', parent=sandy_message.key)
这将为您提供强大的一致性,并授予您查询交易中所有上述实体的能力。
我正在使用get_or_insert
,如果它与提供的密钥不存在,它会在事务中有效地创建实体。这要求密钥或id是唯一的。因此,这样您就不能拥有Greeting
和Sandy as parent
的2封邮件。
键的工作方式就像二叉树。
S = Sandy,M =消息,R =修订
Sandy
/ | \
M1 M2 M3
/ | \ | \
R1 R2 R1 R1 R2
结束或更短的每条路径都可以在交易中运行,并提供强大的一致性*。
回复评论:
由于此示例不足以显示GAE和NDB的效率,因此可能会出现以下情况。
想象一下,每个房间都有一个带有队列的自动点唱机。人们将歌曲排队到每个点唱机的每个队列。
J =自动点唱机,Q =队列,S =歌曲
Jukebox
/ | \
Q1 Q2 Q3
/ | \ | \
S1 S2 S3 S4 S5
在这个示例中,使用路径很方便,因此用户的每个操作,知道自动点唱机,队列可以CUD歌曲实体与点唱机,队列和歌曲一致。
*顺便说一句,你也可以锁定不从root开始的路径
另请注意Queries inside transactions must include ancestor filters