数据模型的选择:要更新和映射的试剂原子的嵌套映射或向量?
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 等
对于留在内存中的小问题,您可以使用库:
- Spectre
- DataScript
- Tupelo.Forest - 我个人的最爱! ;)
现阶段这些可能有些矫枉过正,但您可能希望在以后牢记它们。
我正在开发 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 等
对于留在内存中的小问题,您可以使用库:
- Spectre
- DataScript
- Tupelo.Forest - 我个人的最爱! ;)
现阶段这些可能有些矫枉过正,但您可能希望在以后牢记它们。