couchdb中的唯一约束
是否有实施独特约束的技术/建议?是的,我们可以创建唯一的密钥,但我们不能更改密钥和密钥,而且这种方法不适合复杂的验证(单独的唯一登录、单独的唯一电子邮件等) 例如,一个帐户应该有 独特的登录和电子邮件。导出密钥 从该字段将生成 不一致:couchdb中的唯一约束,couchdb,Couchdb,是否有实施独特约束的技术/建议?是的,我们可以创建唯一的密钥,但我们不能更改密钥和密钥,而且这种方法不适合复杂的验证(单独的唯一登录、单独的唯一电子邮件等) 例如,一个帐户应该有 独特的登录和电子邮件。导出密钥 从该字段将生成 不一致: key1: "Account-john@example.net-john", { email: "john@example.net", login: "john"} key2: "Account-mary@example.net-mary", { email:
key1: "Account-john@example.net-john", { email: "john@example.net", login: "john"}
key2: "Account-mary@example.net-mary", { email: "mary@example.net", login: "mary"}
看起来不错,但是:
key1: "Account-john@example.net-mary", { email: "john@example.net", login: "mary"}
key2: "Account-mary@example.net-mary", { email: "mary@example.net", login: "mary"}
哎呀,现在我们有两个登录名为“mary”的帐户,具体取决于。考虑多主复制的情况,可能有冲突的条目添加在每个主机内一致,但一旦复制它们就不一致。您可能只使用一台couchdb服务器,但一般来说,他们设计它时假设使用多主服务器,并且没有添加任何只在单个未复制服务器中正常工作的功能
如果您只关心单服务器的情况,那么您可以利用网络支持重建CouchJ,并在
validate\u doc\u update()
函数中执行http查询,该函数将对DB执行查询,查看电子邮件地址是否已被使用,如果已被使用,则更新失败。查看有关验证机制的更多详细信息。我不建议这样做,相反,我会在id字段中嵌入所有唯一性(直接或通过哈希),如果用户更改了任何影响的内容,则只需移动文档。这是CouchDB中不太有趣的部分之一。我发现处理可以更改的唯一字段的最佳方法(如在您的用户示例中)是创建具有唯一值的“指针”文档作为键的一个组件,然后使用这些文档声明唯一值。这样做的重要部分是为主文档拥有一个可预测的密钥,然后在保存主文档之前保存唯一的字段声明文档(并允许密钥冲突阻止主文档保存)
给定具有唯一用户名和唯一电子邮件的用户,您的主要文档可能如下所示:
user-1234: { username: "kurt", email: "kurt@localhost" }
user-9876: { username: "petunia", email: "pie@crust.com" }
user-username-kurt: { primary_doc: "user-1234" }
user-email-kurt@localhost: { primary_doc: "user-1234" }
user-username-petunia: { primary_doc: "user-9876" }
user-email-pie@crust.com: { primary_doc: "user-9876" }
唯一的字段指针如下所示:
user-1234: { username: "kurt", email: "kurt@localhost" }
user-9876: { username: "petunia", email: "pie@crust.com" }
user-username-kurt: { primary_doc: "user-1234" }
user-email-kurt@localhost: { primary_doc: "user-1234" }
user-username-petunia: { primary_doc: "user-9876" }
user-email-pie@crust.com: { primary_doc: "user-9876" }
创建或更新用户将采取以下步骤:
此设置还允许您处理关系,而无需担心级联用户密钥。我不知道你的情况,但我的用户文档几乎被系统中的所有其他文档引用。更改用户密钥将是一个巨大的麻烦。核心答案 为具有要保持唯一字段的文档构建POST/PUTs,如下所示:
id
和rev
和GET/yourdb/\u design/yourapp/\u view/viewname?group=true&key=“value-of-your-unique-field-from-step-1”粗略示例 假设您正在存储用户帐户,并且希望确保电子邮件地址是唯一的,但不希望将其作为文档id(无论出于何种原因)。如上所述,构建一个视图以快速检查电子邮件地址的唯一性。我们称之为电子邮件。它将有一个映射函数,可能与此类似
function(doc) {
if(doc.type === 'account') {
emit(doc.email, 1);
}
}
只需将\u count
作为reduce函数。如果您发出一个1像上面的\u sum
也会起作用。如上所示,在您的文档上设置并检查类型
字段只是一种惯例,但有时我觉得它很有用。如果您存储的只是用户帐户,那么您可能不需要它
现在让我们假设我们正在插入这样一个文档
POST /mydb/
{
"name": "Joe",
"email": "joe@example.org"
}
CouchDB会用类似于
{
ok: true,
id: 7c5c249481f311e3ad9ae13f952f2d55,
rev: 1-442a0ec9af691a6b1690379996ccaba6
}
查看我们现在是否有多个joe@example.org在数据库中
GET /mydb/_design/myapp/_view/emails/?group=true&key="joe@example.org"
CouchDB会用类似于
{
rows: [
{
key: "joe@example.org",
value: 1
}
]
}
如果回复中的value
不是1
,那么您可能只是插入了一封重复的电子邮件。因此,删除文档并返回一个错误,其中电子邮件地址必须是唯一的,类似于典型的SQL数据库响应,或者任何您想要的
删除会像这样进行
DELETE /mydb/7c5c249481f311e3ad9ae13f952f2d55?rev=1-442a0ec9af691a6b1690379996ccaba6
简短讨论(如果您愿意) 如果你来自一个好的老地方