如何在CouchDB中实现唯一键约束

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在CouchDB中实现唯一键约束相关的知识,希望对你有一定的参考价值。

我使用CouchDB,我希望所有用户都能收到独特的电子邮件。当我尝试复制电子邮件时,我希望数据库返回状态400(错误请求)。

但由于没有办法在CouchDB中定义约束,我应该自己实现它,我的问题是:

我的应用程序应该在哪个层面遵守此规则?

(1)域对象层 我真的不知道如何在这一层实现它

(2)交互层 这种约束可以在这里的交互者中实现,因为存在业务规则所在的位置。但如果单个文档有多个规则,可能会增加不必要的复杂性......

function createUser(userData)  {
  let email = userData.email;
  let exist = await userDB.userExist(email);

  if(exist) {
    // return status 400
  } else {
    // create user
  }    
}

(3)数据库网关层 约束也可以在数据库网关层中实现。通常我们会为每个特定实体提供一个网关。但这是否意味着外部服务适配器包含一些业务逻辑?

class userDB()  {
  constructor(opts) {
    this.db = opts.db.connect();
  }

  async userExist(email) {
    return await this.db.fetchByView('email', email);
  }

  async create(email) {
    let exist = await this.userExist(data.email);
    if(exist) {
      // throw error
    } else {
      // create the user
    }
  }
}
答案

Unique email address是一个非常古老的DDD话题。它涉及set validation。最简单的(从我的观点来看也是最好的)是在数据库级别设置约束。

据我所知,在CouchDB中创建唯一约束的唯一方法是使用_id字段,以便您可以使用this solution。这个想法是将电子邮件放在_id字段中。

let exists = await this.userExist(data.email);

if(exists){// throw error} else {//创建用户}

此方法对于并发更新不安全。可以同时创建两个用户。想象一下,对于这两个请求,this.userExist(data.email)都返回false。

另一答案

我不是CouchDB专家,但从纯粹的清洁架构角度来看,确保唯一的电子邮件地址是一个应该在交互器中实现的业务规则。

使用这种方法,即使您曾经决定用其他一些细节(另一个存储系统)替换细节CouchDB,您的业务规则仍将保持不变。

以上是关于如何在CouchDB中实现唯一键约束的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中实现广义唯一性 DB 约束 (A,B) 和 (B,A)?

在 Apache Cassandra 中实现 Mysql 或 Psql 关系表(外键约束)功能

如何在 Access 中实现自反主键/外键关系?

你能在 Sqlite3(使用 Django)中实现不区分大小写的“唯一”约束吗?

在多个片段中的片段中实现选项卡

CouchDB 中的短键和唯一键