数据模型的选择:要更新和映射的试剂原子的嵌套映射或向量?

Choice of data model: Nested map or vector for Reagent atom to be updated-in and mapped over?

我正在开发 Reagent 应用程序来管理酒店预订网站的季节。数据显示在表格视图中,当前存储在一个原子中,该原子包含以季节 ID 作为键的嵌套地图,如下所示:

(def seasons (r/atom
{1
 {:begin "2020-04-02"
  :end "2020-04-19"
  :selected false
  …much more data like price per room etc}
2
{:begin "2020-04-20"
  :end "2020-06-18"
  :selected true
  }
…}))

这种结构的主要优点是通过 #(dissoc @seasons season-id)(update-in seasons [season-id :begin] "2020-04-21") 从我的组件中轻松 deleting/modifying 季节,如果采用集成 id 的更扁平的替代方案,这将更加麻烦进入代表季节的地图,如下所示:

(def seasons
(r/atom
[{:id 1
  :begin "2020-04-02"
  :end "2020-04-19"
  :selected false
  …much more data like price per room etc}
 {:id 2
  :begin "2020-04-20"
  :end "2020-06-18"
  :selected true
  }…]))

这个版本更适合映射,这对我当前的数据模型来说不是很愉快,我必须始终将 id 与实际映射重新组合成二进制向量,然后粘贴生成的序列返回 into 一张地图。

我越来越倾向于切换到第二种模型,因为 removal/update 通过将整个赛季传递给一个函数是可行的……那么根本不需要 ID,例如:

(vec (remove #(= % season) @seasons))

或分别为:

(vec (map #(if (= % season) 
       (update-in % [:begin "2020-04-21"]) %) @seasons))

因为这是我的第一个真实世界的 Reagent 应用程序,所以我有点不确定实际上哪种数据模型更可取?这两种方法之间是否有任何性能考虑因素?对于经验丰富的 Reagent 开发人员来说,哪一个看起来更理智?有没有我不知道的第三种方式?

非常感谢您对这个有点开放的问题的任何投入!

当您描述您的目的(季节)时,性能不是考虑因素。每天三个“季节”每年只有约 1000 个——对计算机来说是一个很小的数字。

那么,哪种方法对您的代码来说更简单?您已经讨论了两个用例,一个用例支持方法 A,另一个用例支持方法 B。由您决定。

在方法 A 中,您已经对数据进行了“预先索引”,因此您可以直接转到某个事物并对其进行修改。在方法 B 中,您必须先进行小型搜索才能找到某物,然后再对其进行处理。对于更大的问题,方法 B 最终会变成数据库,如 Postgres、Datomic 或 Neo4J 等

对于留在内存中的小问题,您可以使用库:

现阶段这些可能有些矫枉过正,但您可能希望在以后牢记它们。