CouchDB/PouchDB 中的任意文档排序

Ahm*_*sih 5 database couchdb pouchdb

我正在使用 CouchDB/PouchDB 构建可以被视为幻灯片应用程序的东西:每个“幻灯片”都是它自己的 Couch 文档,幻灯片可以重新排序或删除,并且可以在现有幻灯片之间或在开头或幻灯片结束。一个幻灯片可以从一张幻灯片增加到 10,000 张幻灯片,所以我对空间和时间效率很敏感。

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

但所有这些都涉及

  1. 使用浮点辅助键进行重新排序/创建/删除,并定期对索引进行规范化(即,假设两个文档是 order-index 1.0 和 2.0,然后中间的第三个文档获取键 1.5,然后第四个获取 1.25,…… , 直到 ~31 个文档被插入其中,并且您会遇到浮点精度问题);
  2. 一种链表方法,其中幻灯片文档有一个previousnext字段,其中包含文档的任一侧的主键;
  3. 为每个文档重新排序/插入/删除更新所有文档的非常简单的方法。

这些都不适合 CouchDB:#1 在 SQL 或 CouchDB 中会产生大量的偶然复杂性。#2 不可靠,因为缺乏原子事务(CouchDB 可能会用它的新文档更新前一个文档,next但同时另一个客户端可能已经更新了新的下一个文档,因此更新新的下一个文档将失败并显示 409,并且您的链表被保留在不一致的状态)。出于同样的原因,#3 是完全行不通的。


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

这种方法的一个调整是创建第二个数据库来保存这个订购文档并打开它的自动压缩。跟踪两个数据库连接需要做更多的工作,而且我最终必须将大量数据放到网络上,但我将有一种强大的方式来在 CouchDB 中订购文档。


所以我的问题是:CouchDB 人们通常如何存储文档的顺序?更有经验的 CouchDB 人员能否看到我上面概述的方法中的任何缺陷?

Ahm*_*sih 5

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


归档时间:

查看次数:

593 次

最近记录:

8 年,7 月 前