2017-06-20 46 views
4

Datomic中沒有現成的模式特性用於在多對多關係中對子實體進行排序,但這是一個非常普遍的要求。谷歌搜索已經發現了一些解決方案,所以我想在此清點各種需求和解決方案,並希望得到社區的意見。如何在Datomic中實現排序的一對多關係?

可能要求

  • R1:少數孩子的實體(N)(不知道的小/大 門檻應該是什麼)
  • R2:大量子實體的
  • R3:單親兒童
  • R4:多父母子女
  • R5:遞歸子女,即存儲在Datomic中的樹

我的特殊使用案例是R1 + R3 + R5,我認爲這很常見,但我想盡可能多地列舉,以便將來可以成爲其他人的有用參考。

問題實體

每個解決方案似乎公頃面臨挑戰。我能想到的是:

  • P1:保持插入,刪除或移動操作的恆定時間操作。已經有建議使用小數來表示「位置」值,以避免在重新排序時更新所有的孩子。
  • P2:支持與訂購的多個父親關係
  • P3:維護存儲的位置或邊的複雜性訂購或訂購更改。
  • P4:更改爲「位置」屬性影響隱含「上次更改」日期子實體時,它實際上並沒有改變
  • P5:查詢/拉(特別是遞歸查詢)通過包裝連接時變得困難實體

對於我的樹用例,我不關心P2和P1是不是一個大問題,因爲N個總體上是低

所有這些研究並沒有幫助我找到哪個溶液的澄清度最適合我的樹用例,但我傾向於S2。自然,最簡單的複雜性是我的目標,但我懷疑所有的解決方案都是複雜的。

問題:你對這個問題有什麼經驗,你可以分享什麼,這將有助於他人決定?正如他們指出的那樣,我會在上面添加更多的R,S和P。我(和其他許多人)會真正感謝任何反饋。

A similar question在幾年前被問到,但在那裏發生的事情並不多。

+0

你確定S2的鏈接是正確的嗎? –

+0

同意,該帖子沒有明確說明訂單要求。我添加了另一個。 –

回答

0

爲了將來的參考,我通過使用帶有拉鍊的Datomic Linked List包裝,對我的要求(有序樹存儲)取得了很好的成功。鏈表列表中有一些錯誤,我將盡快將它們修改/部署到clojars。

該解決方案非常簡單,並且具有恆定的更改操作時間,因此表現良好。

一個挑戰是多重訂購的兒童關係。鏈表代碼假定每個實體都有一個有序列表,在我的情況下,我需要1個樹形子代表列表,但其他數據列表更多。我已經解決了這個問題,但如果您的要求相似,則需要考慮。

如果從這個原型出現其他有用的觀察結果,我會發表進一步的意見。

+0

使用zipper/linkedlist的缺點是你不能使用遞歸數據查詢來讀取完整的樹。這不是一個大問題,因爲d/pull是一個便宜的操作,所以每個節點調用一次就很快 –

0

這實際上取決於您的實際使用情況(您可能同時在單個數據庫中有多個不同的數據庫)。

首先,選擇one-to-manymany-to-many之間的父子關係:

  • one-to-many意味着你能堅持額外的屬性右轉到子實體,避免了額外:db/id:my.domain/guid:ordinal/ref屬性花費寶貴的datoms和歷史尺寸。
  • many-to-many意味着你必須有獨立的實體來跟蹤孩子之間的順序。

在這一點上,你可能還是要選擇獨立的實體,以避免搞亂了一些latest change date統計/兒童實體訂閱,如果您有任何。在語義上,改變兒童的順序意味着父母實體已經改變,而不是兒童。

接下來,得到recursive pull patterns and queries的問題。如果你去了attribute on child - 你已經很好了。 如果用separate entity去,守序的實體在父實體單獨的屬性:

{:foo/bars [{:db/id 4} 
      {:db/id 2}] 
:foo/bars-order [{:db/id 9 :ordinal/idx 0 :ordinal/ref {:db/id 2}} 
        {:db/id 8 :ordinal/idx 1 :ordinal/ref {:db/id 4}}]} 

壞處就是:你需要保持兩個同步,以避免孤兒序,或下落不明的孩子。

最後,linked listposition values更有趣味。但是,positional values具有較大的尺寸tx-data尺寸(例如,在10個元素列表的位置插入單個元素需要10個額外的數據元,在添加新元素之前觸摸每10個元素)。

我認爲,唯一沒什麼問題的解決方案是包裝兒童(parent-wrapper-child),它會從您身上帶走遞歸拉式,並以其他方式阻礙。

現在回到你的使用情況:兒童
single-parent + recursive queries = idxnext屬性。

+0

謝謝米沙,你指出了兩個我已經添加到原始問題中的問題以供參考。我將使用https://github.com/dwhjames/datomic-linklist來試用S3,看看它是如何工作的。仍然會歡迎更多的反饋意見,來自其他人的體驗報告...... –

+0

謝謝@clojuremostly,這就是我在P1描述中的含義。如果我將:position作爲數字,我會這樣做,但是,我在鏈接列表的一半,似乎在工作。我會隨時更新。仍然希望聽到更多的人與經驗報告,以便社區可以相信這是一個平衡的調查什麼是有效的調查。 –

+0

哎呀,沒有正確閱讀。刪除了噪音。對不起'回合。 – ClojureMostly

相關問題