【问题标题】:Datastore entity key collision数据存储实体键冲突
【发布时间】:2012-05-16 05:16:16
【问题描述】:

在开发中,我有一个空的数据存储。 在线 我有一个包含数百万实体的数据存储。

在开发数据存储(本地)中,我放置了一个新实体(生成新密钥)。 然后我导出实体并将其放入在线数据存储中(使用本地生成的密钥)。本地生成的密钥已经分配给在线数据存储中的实体有什么风险?

或者通过像这样在本地创建密钥来避免冲突是否更简单:

for (int i = 0; i < data.size(); i++) {
    Key k = KeyFactory.createKey(kind, new Date() + i);
    // continue to creating and inserting entities...
}

谢谢。

【问题讨论】:

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


    【解决方案1】:

    来自https://developers.google.com/appengine/docs/java/datastore/entities

    而不是使用键名字符串或生成数字 ID 自动,高级应用程序有时可能希望分配 将他们自己的数字 ID 手动添加到他们创建的实体中。意识到, 但是,没有什么可以阻止 Datastore 分配 您的一个手动数字 ID 到另一个实体。唯一的办法 避免此类冲突的方法是让您的应用程序获取 ID 块 使用方法 DatastoreService.allocateIds() 或 AsyncDatastoreService.allocateIds()。数据存储区的自动 ID 生成器将跟踪已分配给这些的 ID 方法,并将避免将它们重用于另一个实体,因此您可以 安全地使用此类 ID 而不会发生冲突。

    您必须手动生成所有数字键(并且以不会发生冲突的方式)或使用allocateIds()。除非您使用该功能,否则无法保证您手动生成的任何内容都不会与现有密钥发生冲突。生成的 key id 不像关系数据库中的自动递增字段,每次递增一。

    【讨论】:

    • 我明白了,但是在这里我们讨论的是在开发模式下将实体(因此创建密钥)放在本地数据存储中,然后将它们导出到生产在线数据存储,所以在我看来在这种情况下,防止冲突的唯一方法是使用某种与时间相关的 ID/名称来创建密钥。
    • 只有当你以这种方式生成 100% 的实体键时才会起作用(即,在没有 id 的情况下准确地执行 0 次放置),并且以这样的时间分辨率进行,以创建零重复。如果您已经以正常方式创建了 1 个实体,它可能会失败。
    【解决方案2】:

    这取决于您在实体上拥有的 ID 类型。如果它们是整数,它们很小,很容易发生冲突。

    我建议创建与 Google 默认使用的密钥格式略有不同的密钥格式。只要 KeyFactory 使用时钟的全部精度(即不会停在几秒钟),您上面的函数就应该可以工作。

    【讨论】:

    • 我从不设置任何键的任何 ID。它们都是标准的,在我第一次放置实体时自动分配。在虚拟关系中,我使用 KeyFactory.keyToString()。
    • 所有实体都是使用new Entity(kind)创建的
    【解决方案3】:

    当数据存储生成键时,ID 是整数。如果您使用 Strings 作为 Id 生成键,那么它们不会覆盖现有实体。

    a.key.id() == 1
    b.key.id() == '1'
    a.key.id() != b.key.id()
    

    【讨论】:

      【解决方案4】:

      您应该提供有关您的用例的更多信息,以便任何人提出适当的解决方案。例如,您可以像这样在 dev 数据库上创建密钥:

        KeyFactory.createKey(entity, "dev_" + UUID.randomUUID())
      

      另一种选择是创建一个小型实用程序或应用程序,该实用程序或应用程序将从本地数据库中检索实体,然后将其发布到开发数据库。获取 POST 的在线服务器将创建一个新实体并从客户端分配除密钥之外的所有属性,从而让 GAE 自动生成新密钥。然后可以将新密钥发送回客户端,作为对 POST 操作的响应。

      同样,我不知道您以后是否想更新本地数据库以与在线重新同步,但如果是这样,定义您自己的密钥的第一种方法将起作用,因为下一次同步将在线更新实体。

      【讨论】:

        猜你喜欢
        • 2018-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-19
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        相关资源
        最近更新 更多