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

时间:2017-01-08 19:21:14

标签: google-app-engine go google-cloud-datastore

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

  1. 提供您自己的字符串或int64 ID。
  2. 不要提供这些内容,让AE为您分配int64个ID。
  3. 预分配int64个ID。
  4. documentation有关于ID生成的说法:

    这(1):

      

    可以将云数据存储配置为使用两个生成自动ID   不同的自动ID政策:

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

    2.   
    3. 旧版策略会创建一系列非连续的较小整数ID。

    4.         

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

    和这(2):

      

    注意:而不是使用键名字符串或生成数字ID   自动,高级应用程序有时可能希望分配   他们自己的数字ID手动到他们创建的实体。意识到,   但是,没有什么可以阻止Cloud Datastore   将您的一个手动数字ID分配给另一个实体。唯一的   避免此类冲突的方法是让您的应用程序获得阻止   具有datastore.AllocateIDs函数的ID。云数据存储区   自动ID生成器将跟踪已分配的ID   使用此功能,将避免重用它们为另一个实体,所以   你可以安全地使用这些ID而不会发生冲突。

    和这(3):

      

    Cloud Datastore会生成随机的未使用ID序列   近似均匀分布。每个ID最多可以为16位小数   数字很​​长。

         

    系统分配的ID值保证对于实体组是唯一的。   如果将实体从一个实体组或命名空间复制到另一个实体   并希望保留密钥的ID部分,一定要分配   ID首先阻止Cloud Datastore为a选择该ID   未来的任务。

    我有一个与祖先一起存储的特定实体类型。但是,我希望拥有全局唯一ID和AE的ID(通过 datastore.AllocateIDs 与Go分配)在存储在祖先下时(在实体组)。因此,预分配可以解决这个问题(他们是祖先不可知的)。但是,显然会给出一个响应间隔...已保留的连续ID范围。

    是否有某种方法可以预先分配那些漂亮,不透明,统一分布的ID?

    虽然我们关注这个主题,但我假设来自AE的不透明ID是某些伪随机数生成器的结果,每个实体类型都有一个持久状态,但是单词" track&# 34;在(2)中似乎暗示乐观地生成和缓冲可能未使用的ID存在成本。如果有人能澄清这一点,那就太好了。

1 个答案:

答案 0 :(得分:0)

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

尝试为实体分配新ID时:

重复以下步骤:

  • 生成随机 K 位整数。将其用于实体ID字段。 [使用统一的随机分布]
  • 创建云数据存储区事务。
  • 插入新实体。 [如果交易因实体已经存在而中止,请再次使用新的随机数]

如果你使 K 足够大(例如128)并且有一个正确播种的随机数生成器,那么统计上不可能产生ID冲突,你可以删除重试循环。

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