如何保证 CouchDB 文档中字段的唯一性?
正如罐头上所说的那样。我有一堆(比如说)会员文档,我希望每个用户都能够将其文档上的电子邮件字段设置为他想要的任何内容,例如另一个文档中存在的电子邮件。如果我只是进行检查插入,我很容易受到竞争条件的影响。是否有一些“锁定”或插入然后检查的惯用语?
Just what it says on the tin. I have a bunch of (say) Member documents, I want each user to be able to set the Email field on his document to whatever he wants, example an Email that exists on another document. If I just do a check-insert, I'm vulnerable to a race condition. Is there some idiom for "locking" or inserting-then-checking?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
唯一可靠的方法是创建一个具有唯一值作为文档 ID 的文档。
The only sure way is to create a doc with the unique value as doc id.
正如其他答案所指出的,CouchDB 中保证唯一的唯一字段是 _id。
你可以从这里的复制器那里借用一个技巧。为了在相同的两台主机之间快进第二次复制,它会编写一个检查点文档来记录它上次到达的更新序列。但它以后如何找到检查点文档呢?像这样;
"_id": md5(source.host + source.port + target.host + target.port)
可以提取通用模式,其中唯一字段构成 id 本身的一部分。通过 md5 运行它们可以保证固定长度的标识符。
就您而言,您可以仅使用电子邮件地址作为您的 ID。
更改这些字段之一是一个两步过程,但仍保持唯一性属性。
崩溃步骤 1 和 2 之间将保留旧文档,因此您可能希望在新文档中添加对旧文档的引用。然后,您可以创建这些反向引用的视图并定期执行清理扫描。
话虽如此,CouchDB 故意只支持一个唯一字段,而不是典型的 RDBMS,它可以支持复杂的关系约束,以便解决方案能够在集群中干净地扩展(参见 BigCouch)。在您的情况下,电子邮件地址必须是唯一的,我所说的大部分内容都应该有效(电子邮件地址不会经常更改),但显然这在某种程度上是逆流而上的。
哈特哈,
B.
As the other answer notes, the only field guaranteed to be unique in CouchDB is _id.
You might borrow a trick from the replicator here. In order to fast-forward a second replication between the same two hosts, it writes a checkpoint document which records the update sequence it last reached. But how does it find the checkpoint document in the future? Like so;
"_id": md5(source.host + source.port + target.host + target.port)
A general pattern can be extracted where your unique fields form part of the id itself. Running them through md5 guarantees a fixed length identifier.
In your case, you could just use email address as your id.
Changing one of these fields is a two step process, but one that still maintains the uniqueness property.
A crash between steps 1 and 2 will leave the old document it place, so you may wish to add a reference to the old document in the new document. You can then create a view of those back references and perform a clean up sweep periodically.
All that said, CouchDB deliberately only supports only one unique field, as opposed to a typical RDBMS which can support elaborate relational constraints, in order for a solution to scale up cleanly in a cluster (c.f, BigCouch). In your case, where email address must be unique, much of what I've said should work (email addresses don't change that often), but obviously this is swimming upstream to a degree.
HTH,
B.