如何防止 Google Cloud Datastore 中出现重复值?

How do I prevent duplicate values in Google Cloud Datastore?

是否有任何机制可以防止我的实体的某些字段出现重复数据?类似于 SQL unique.

否则,人们通常使用什么技术来防止重复值?

在 SQL 中对 UNIQUE 约束进行等效操作的唯一方法在像 Cloud Datastore 这样的无SQL 存储系统中无法很好地扩展。这主要是因为它需要在每次写入之前进行一次读取,以及围绕这两个操作的事务。

如果这不是问题(即,您不经常写入值),该过程可能类似于:

  1. 开始可序列化事务
  2. 查询所有种类以匹配 属性 = 值
  3. 如果查询有匹配项,则中止交易
  4. 如果没有匹配项,插入新实体 属性 = value
  5. 提交交易

使用 gcloud-python,这可能看起来像...

from gcloud import datastore
client = datastore.Client()

with client.transaction(serializable=True) as t:
    q = client.query(kind='MyKind')
    q.add_filter('property', '=', 'value')

    if q.fetch(limit=1):
        t.rollback()
    else:
        entity = datastore.Entity(datastore.Key('MyKind'))
        entity.property = 'value'
        t.put(entity)
        t.commit()

注意:Transactions 上的 serializable 标志在 gcloud-python 中相对较新。有关详细信息,请参阅 https://github.com/GoogleCloudPlatform/gcloud-python/pull/1205/files


要做到这一点,"right way" 是设计您的数据,使关键是您对 "uniqueness" 的衡量,但在不了解您想要做什么的情况下,我不能不多说了

上面给出的方法在数据存储区中不起作用,因为您无法在事务内跨任意实体进行查询。如果您尝试,将抛出异常。

但是,您可以通过为每个唯一字段使用新类型并在交易中执行 "get"(按键查找)来实现。

例如,假设您有一个 Person 种类,并且您想要确保 Person.email 是唯一的,您还需要一个种类,例如UniquePersonEmail。这不需要被任何东西引用,但它只是为了确保唯一性。

  1. 开始交易
  2. 获取 ID = theNewAccountEmail 的 UniquePersonEmail
  3. 如果存在则中止
  4. 将 UniquePersonEmail 与 id = theNewAccountEmail
  5. 将 Person 与所有其他详细信息(包括电子邮件)放在一起
  6. 提交交易

因此您最终需要进行一次读取和两次写入来创建您的帐户。