在CouchDB中生成自动递增数字ID的方法

aku*_*aku 25 couchdb auto-increment

由于CouchDB不支持SQL类似的AUTO_INCREMENT,您的方法是为文档生成顺序唯一数字ID?

编辑:

我需要数字ID有几个原因:

  • 用户友好的ID(例如TASK-123,RQ-001等)
  • 与需要数字主键的库/系统集成

我知道复制等问题.这就是为什么我对人们如何克服这个问题感兴趣.

Jas*_*ith 36

正如Dominic Barnes所说,自动增量整数不可扩展,不适合分布式或云友好.现在似乎每个应用程序都需要具有离线支持的移动版本,并且它与自动增量整数不直接兼容.我们都知道这一点,但确实如此:自动增量整数对于遗留代码是必要的,可以说是其他东西.

在这两种情况下,您都负责生成自动递增整数.视图正在运行emit(the_numeric_id, null).(你也可以有一个"类型"命名空间,例如by emit([doc.type, the_numeric_id], null).查询最后一行(例如用a startkey=MAXINT&descending=true&limit=1,递增返回的值,这是你的下一个id.保存的尝试是在一个循环中,如果有的话可以重试碰撞

如果您不需要100%密度的ID列表,也可以玩技巧.例如,您可以向emit()行添加时间戳,并估计文档创建速度,并按该速度乘以计算和传输时间.您也可以简单地增加1到N之间的随机整数,因此大多数时候第一个插入工作,代价是非同类ID号.

关于存储整数的位置,我认为有id策略和try和check策略.

ID的策略是在简单和快捷短期.文档ID是一个整数(可能以添加命名空间的类型为前缀).由于Couch保证了_id场上的独特性,你只需担心自动递增.在循环中执行此操作:409 Conflict触发重试,201 Accepted意味着您已完成.

我认为这个技巧的主要痛苦是,如果你遇到冲突,你有两个完全不相关的文件,其中一个必须被复制到一个新文件中.如果与其他文件存在关系,则必须全部纠正.(emit(key, {_id: some_foreign_doc_id})想到CouchDB 0.11 技巧.)

尝试和检查策略使用默认的UUID的doc._id,所以每次插入会成功.理想情况下,所有或大多数文档间关系都基于不可变的UUID _id,而不是整数.这只是用于用户和UI.自动递增整数只是文档中的一个字段{"int_id":20}.当然,观点确实如此emit(doc.int_id, null).(您可以使用?key=23?include_docs=true视图的参数按整数id查找文档.

当然,在复制之后,您可能会遇到ID冲突(不是官方的CouchDB冲突,而只是使用相同数字ID的文档).通过ID发出的视图也将具有缩减阶段:_count应该足够了.接下来,您必须巡逻数据库,查询此视图?group=true并查找计数> 1的任何行(对应于整数ID).在正面,更正文档的数字ID是一个小的更改,因为它不是需要新文档创建.

这些是我的想法.既然我把它们写下来了,我觉得你必须做关系牧养,无论id存储在哪里; 所以也许使用_id更好.我看到的唯一另一个缺点是,你永远与一个根本破坏的命名模型结合 - 对于"永久"的某些定义.


Dom*_*nes 5

您是否有任何特殊原因想要使用数字 ID 而不是 CouchDB 可以为您生成的 UUID?UUID 非常适合 CouchDB 使用的分布式范例,请坚持使用内置内容。

如果您发现自己的架构中存在超过 1 个 CouchDB 节点,并且在复制时依赖于“自动增量”之类的内容,那么您将会遇到冲突的文档 ID。即使您现在只使用 1 个节点,情况也可能并不总是如此,特别是因为 CouchDB 在分布式和“离线”架构中运行得很好。

  • 我需要简短的人类可读 ID。我目前不关心可扩展性,但我更愿意避免复制的潜在问题 (2认同)