我正在使用CouchDB/PouchDB构建一个幻灯片应用程序:每个“幻灯片”都是自己的Couch文档,可以重新排序或删除幻灯片,并且可以在现有幻灯片之间或幻灯片的开头或结尾添加新幻灯片。一个幻灯片集可以从一个到约10,000张幻灯片,因此我对空间和时间效率非常敏感。
我首先制作了幻灯片创建/编辑功能,完全低估了跟踪幻灯片排序的难度。这很难做到,因为每个幻灯片文档的顺序完全独立于幻灯片文档本身,即它不是我可以按时间或文档中包含的某个数字进行排序的东西。我在StackOverflow上看到了许多关于如何在关系数据库中跟踪排序的问题:
我正在评估的一种面向CouchDB的方法是创建一个仅包含幻灯片排序的文档:它可能包含一个主键到排序号的哈希对象以及一个将排序号转换为主键的数组,并且在重新排序/插入/删除幻灯片时只需更新此对象。缺点是Couch会为每个排序更改(重新排序/插入/删除)保留此潜在大的文档的副本,CouchDB不支持紧缩单个文档,而且我不想对整个数据库运行压缩,因为我喜欢保留每个幻灯片文档的历史记录。另一个缺点是,在成千上万张幻灯片之后,每次更改排序都需要从PouchDB/客户端传输整个对象(数百千字节)到Couch。
对此方法进行微调的方法是创建第二个数据库来保存此排序文档,并在其上启用自动压缩。维护两个数据库连接会更费力,而且最终我将不得不通过网络传输大量数据,但我将拥有一种在CouchDB中对文档进行排序的稳健方法。
所以我的问题是:CouchDB的人通常如何存储文档的顺序?更有经验的CouchDB人员是否能看出我上面概述的方法中存在任何缺陷?
我首先制作了幻灯片创建/编辑功能,完全低估了跟踪幻灯片排序的难度。这很难做到,因为每个幻灯片文档的顺序完全独立于幻灯片文档本身,即它不是我可以按时间或文档中包含的某个数字进行排序的东西。我在StackOverflow上看到了许多关于如何在关系数据库中跟踪排序的问题:
但所有这些都涉及以下内容:
- 使用浮点型的次要键进行重新排序/创建/删除,定期规范化索引(例如,假设两个文档的排序索引为1.0和2.0,然后插入一个介于它们之间的第三个文档并获得关键字1.5,然后第四个文档获得1.25,直到插入约31个文档并出现浮点精度问题);
- 使用链接列表方法,其中幻灯片文档具有包含其两侧文档的主键的“previous”和“next”字段;
- 每次文档重新排序/插入/删除都更新所有文档的非常简单的方法。
这些方法都不适用于CouchDB:#1在SQL或CouchDB中会产生大量的附加复杂性。#2由于缺乏原子事务而不可靠(CouchDB可能会更新先前文档的新“下一个”,但另一个客户端可能已经同时更新了新的下一个文档,因此更新新的下一个文档将失败并导致链接列表处于不一致状态)。出于同样的原因,#3是完全不可行的。
我正在评估的一种面向CouchDB的方法是创建一个仅包含幻灯片排序的文档:它可能包含一个主键到排序号的哈希对象以及一个将排序号转换为主键的数组,并且在重新排序/插入/删除幻灯片时只需更新此对象。缺点是Couch会为每个排序更改(重新排序/插入/删除)保留此潜在大的文档的副本,CouchDB不支持紧缩单个文档,而且我不想对整个数据库运行压缩,因为我喜欢保留每个幻灯片文档的历史记录。另一个缺点是,在成千上万张幻灯片之后,每次更改排序都需要从PouchDB/客户端传输整个对象(数百千字节)到Couch。
对此方法进行微调的方法是创建第二个数据库来保存此排序文档,并在其上启用自动压缩。维护两个数据库连接会更费力,而且最终我将不得不通过网络传输大量数据,但我将拥有一种在CouchDB中对文档进行排序的稳健方法。
所以我的问题是:CouchDB的人通常如何存储文档的顺序?更有经验的CouchDB人员是否能看出我上面概述的方法中存在任何缺陷?