2016-08-24 64 views
2

我在構建CouchDB/PouchDB的幻燈片應用程序:每個「幻燈片」都是自己的Couch文檔,幻燈片可以重新排序或刪除,新的幻燈片可以添加到現有幻燈片之間或放映幻燈片的開頭或結尾。幻燈片放映可能會從1張幻燈片增加到10,000張幻燈片,所以我對空間和時間效率非常敏感。CouchDB/PouchDB中的任意文檔排序

我先製作了幻燈片創建/編輯功能,完全低估了跟蹤幻燈片排序的難度。這很難,因爲每個幻燈片文檔的順序完全獨立於幻燈片文檔本身,即它不是我可以按時間排序或文檔中包含的某個數字。我看到有關如何跟蹤訂單的關係數據庫StackOverflow上許多問題:

但所有這些使用用於重排序/創建/刪除一個浮點二級密鑰,帶有索引(即,假設兩個文件是順序索引1.0和2.0,然後第三文檔的週期性正常化涉及任一

  1. 在之間獲得關鍵1.5,然後第四獲得1.25,...,直到〜31文檔被插入之間,你會得到浮點精度問題);
  2. 鏈接列表方法,其中幻燈片文檔具有包含文檔主鍵的previousnext字段;
  3. 更新每個文檔重排序/插入/刪除的所有文檔的非常直接的方法。

這些都不適用於CouchDB:#1在SQL或CouchDB中引發了大量偶然的複雜性。 #2由於缺少原子事務而不可靠(CouchDB可能會使用新的next來更新以前的文檔,但另一個客戶端可能同時更新了新的下一個文檔,因此更新新的下一個文檔將失敗並顯示409,並且還剩下鏈接列表處於不一致的狀態)。出於同樣的原因,#3是完全不可行的。


一個CouchDB的導向方式,我評價將創建只包含幻燈片的順序文件:它可能包含一個主鍵,按訂單數哈希對象和數組,將訂單號轉換爲主鍵,並在重新排序/插入/刪除幻燈片時更新此對象。不利之處在於,Couch會爲每個訂單更改(重新排序/插入/刪除)保留一份可能較大的文檔副本-CouchDB不支持僅壓縮單個文檔,並且我不想在我的上執行壓縮整個數據庫,因爲我喜歡保存每個幻燈片文檔的歷史。另一個缺點是,在成千上萬的幻燈片之後,每次更改排序都需要將整個對象(數百千字節)從PouchDB /客戶端傳輸到Couch。

對這種方法的一個調整就是製作第二個數據庫來保存這個訂購文檔並打開自動壓縮。跟蹤兩個數據庫連接還有更多的工作要做,而且我最終不得不將大量數據放在網絡中,但我將有一個可靠的方式在CouchDB中訂購文檔。


所以我的問題是:CouchDB人通常如何存儲文檔的順序?更多有經驗的CouchDB人可以看到我上面概述的方法中的任何缺陷嗎?

+2

可能是有趣的:http://stackoverflow.com/questions/38923376/return-a-new-string-that-sorts-between-two-given-strings –

+1

@LynHeadley謝謝你 - 我正在研究一個超級版本的[m69的答案](http://stackoverflow.com/a/38927158/500207),我認爲這將非常適合CouchDB對查詢上一個/下一個主ID的很好支持! –

+0

真棒!我一直在思考這個問題,並從未在網絡上找到任何好的答案。也許我們正在嘗試... –

回答

0

感謝@LynHeadley的提示,我寫了一個可以細分字符串之間的字典間隔的庫:Mudder.js。這使我可以無限地插入和移動CouchDB中的文檔,通過隨意創建新的密鑰,而無需任何輔助文檔開銷來存儲排序。我認爲這是解決這個問題的正確方法!

1

基於我讀過的內容,我會選擇「訂購文檔」方法。 (即:每個幻燈片文檔都有一個ID數組的幻燈片文檔)這非常簡單,並且完成了用例,所以我不會讓這些問題影響乾淨/直觀的代碼。

你說得對,這個文件可能增長很大,並且由於這個特定文件的重寫性質而複雜化。這就是爲什麼壓縮存在並且是解決方法,所以你不應該在這一點上與CouchDB抗爭。

這是一個常見的誤解,您可以使用CouchDB的修訂歷史記錄來保存數據庫的全面歷史記錄。修改僅僅是爲了幫助編寫併發性,而不是作爲完整版本的控制系統。

CouchDB在默認情況下啓用了自動壓縮功能,如果沒有它,數據庫的大小將會增加未選中狀態。因此,你應該放棄使用這種方法跟蹤文檔歷史的想法,而應採用另一種更安全的替代方案。 (這些選項的列表超出了本答案的範圍)

+0

當你說「CouchDB默認啓用了自動壓縮功能」時,你的意思是['_revs_limit'選項](http://docs.couchdb.org /en/1.6.1/api/database/misc.html#db-revs-limit),默認爲1000,即CouchDB將保留不超過1000個修訂版本? 1000仍然很多,所以不會自動壓縮(每次寫入後立即丟棄非葉節點)仍然很重要 - 因此需要第二個數據庫? –

+0

如果Couch的修訂版本系統不提供它,請注意,或者給CouchDB之上或之外的「適當」版本控制指示一個指針? (我打算將它作爲一個非常溫和的「撤銷」系統來使用,在這種災難中,我至少可以閱讀舊版本的文檔,但是您根據這些意見所做的評論讓我覺得我不應該期望能夠做到那。) –

+1

我會閱讀他們關於壓實的文檔,特別是關於[自動壓縮]的這一節(http://docs.couchdb.org/en/1.6.1/maintenance/compaction.html#automatic-compaction) –