AppEngine,DataStore:预分配正态分布的ID(*不是*单调递增)



在数据存储实体上设置ID有三种方案:

  1. 提供您自己的字符串或int64ID
  2. 不要提供它们,让AE为您分配int64ID
  3. 预先分配一个int64ID块

文档中有关于ID生成的内容:

此(1):

云数据存储可以配置为使用两个不同的自动识别策略:

  1. 默认策略生成未使用ID的随机序列,这些ID大致均匀分布。每个ID最多可以是16十进制数字长。

  2. 传统策略创建一个非连续的较小整数ID序列。

如果要向用户显示实体ID,和/或取决于他们的订单,最好的做法是使用手动分配。

和this(2):

注意:不要使用关键字名称字符串或生成数字ID高级应用程序有时可能希望自动分配他们自己的数字ID手动添加到他们创建的实体中。请注意,但是,没有什么可以阻止云数据存储将一个手动数字ID分配给另一个实体。唯一避免此类冲突的方法是让您的应用程序获得一个块的ID。AllocateID函数。云数据存储自动ID生成器将跟踪已分配的ID并将避免将它们重新用于另一个实体,因此您可以安全地使用此类ID而不会发生冲突。

和this(3):

云数据存储生成未使用ID的随机序列近似均匀分布。每个ID最多可以是16位小数数字长度。

系统分配的ID值保证对实体组是唯一的。如果将实体从一个实体组或命名空间复制到另一个并且希望保留密钥的ID部分,请确保分配ID优先,以阻止云数据存储为未来的任务。

我有一个与祖先一起存储的特定实体类型。但是,我希望拥有全局唯一的ID,并且AE的ID(通过数据存储分配。AllocateIDswith Go)在存储在祖先(实体组中)下时不会是全局唯一的。因此,预分配可以解决这个问题(它们是祖先不可知论者)。然而,很明显,你会得到一段时间的回应。。。已保留的ID的连续范围。

难道没有办法预先分配那些漂亮、不透明、统一分布的ID吗

当我们讨论这个主题时,我假设AE中的不透明ID是某个伪随机数生成器的结果,每个实体类型都有一个持久状态,但(2)中的"track"一词似乎意味着乐观地生成和缓冲可能不会使用的ID是有代价的。如果有人能澄清这一点,那就太好了。

简单的解决方案是执行以下操作:

尝试为实体分配新ID时:

重复以下步骤:

  • 生成一个随机的K位整数。将其用于实体ID字段[使用均匀随机分布]
  • 创建云数据存储事务
  • 插入新实体[如果事务由于实体已经存在而中止,请使用新的随机数重试]

如果您使K足够大(例如128),并且有一个适当的种子随机数生成器,那么从统计角度来看,不可能生成ID冲突,您可以删除重试循环。

如果使K足够大,请停止使用实体键中的integer id字段,而是使用字符串one。Base64 URL将随机数编码为字符串。