CouchDB / PouchDB

时间:2016-08-24 13:45:57

标签: database couchdb pouchdb

我正在使用CouchDB / PouchDB构建可以视为幻灯片应用程序的内容:每个“幻灯片”都是自己的Couch文档,幻灯片可以重新排序或删除,新幻灯片可以添加到现有幻灯片之间或者幻灯片的开头或结尾。幻灯片可以从1到10,000张幻灯片增长,因此我对空间和时间效率非常敏感。

我首先制作了幻灯片创建/编辑功能,完全低估了跟踪幻灯片排序的难度。这很难,因为每个幻灯片文档的顺序完全独立于幻灯片文档本身,即,它不是我可以按时间排序或文档中包含的某些数字。我在StackOverflow上看到了很多关于如何跟踪关系数据库中的排序的问题:

但所有这些都涉及

  1. 使用浮点二级密钥进行重新排序/创建/删除,并定期对索引进行规范化(即,假设两个文档是订单索引1.0和2.0,然后其间的第三个文档获取密钥1.5,然后第四个获取1.25,...,直到~31之间插入文档,你得到浮点精度问题);
  2. 一种链接列表方法,其中幻灯片文档的previousnext字段包含其两侧文档的主键;
  3. 更新每个文档重新排序/插入/删除的所有文档的非常简单的方法。
  4. 这些都不适合CouchDB:#1在SQL或CouchDB中引发了大量的附带复杂性。由于缺少原子事务,#2不可靠(CouchDB可能会使用新的next更新以前的文档,但另一个客户端可能同时更新了新的下一个文档,因此更新新的下一个文档将失败,409,链表处于不一致状态)。出于同样的原因,#3完全不可行。

    我正在评估的一种面向CouchDB的方法会创建一个只包含幻灯片排序的文档:它可能包含一个主键到订单号的哈希对象以及一个转换订单号的数组-to-primary-key,只需在重新排序/插入/删除幻灯片时更新此对象。这样做的缺点是Couch会为每个订单更改保留这个可能很大的文档的副本(重新排序/插入/删除)-CouchDB不支持压缩单个文档,我不想在我的上运行压缩整个数据库,因为我喜欢保存每个幻灯片文档的历史。另一个缺点是,在数千张幻灯片之后,每次更改订单都需要将整个对象(数百KB)从PouchDB /客户端传输到Couch。

    对这种方法的调整是制作第二个数据库,只是为了保存这个订购文件并打开它的自动压缩。跟踪两个数据库连接会有更多的工作,我最终还是要把大量的数据放在网络上,但是我会有一个强大的方法在CouchDB中订购文档。

    所以我的问题是:CouchDB人员通常如何存储文件的顺序?更有经验的CouchDB人员可以看到上述方法中的任何缺陷吗?

2 个答案:

答案 0 :(得分:3)

感谢@LynHeadley的一个提示,我结束了编写一个可以细分字符串之间的字典间隔的库:Mudder.js。这允许我通过随意创建新密钥无限地插入和移动CouchDB中的文档,而无需任何辅助文档的开销来存储排序。我认为这是解决这个问题的正确方法!

答案 1 :(得分:2)

根据我所阅读的内容,我会选择"订购文件"做法。 (即:每个幻灯片文档都有一个id数组的幻灯片文档)这非常简单并且完成了用例,因此我不会让这些问题妨碍干净/直观的代码。

你是对的,这个文件可能会变得非常大,而且该特定文档的写入性质更加复杂。这就是为什么压缩存在并且是解决方案的原因,所以在这一点上你不应该与CouchDB作斗争。

一个常见的误解是,您可以使用CouchDB的修订历史记录来保存数据库的综合历史记录。修订只是为了帮助写入并发,作为完整版本控制系统。

默认情况下,CouchDB启用了自动压缩功能,如果没有它,您的数据库的大小将不会被选中。因此,您应该放弃使用此方法跟踪文档历史记录的想法,而是采用另一种更安全的替代方法。 (这些替代方案的列表超出了本答案的范围)