Fork me on GitHub
#clojuredesign-podcast
<
2019-11-14
>
nate17:11:12

@joshlemer I think the answer depends on what the purpose of your data is. You could flatten it into 4 rows, like this:

[{:user/id 1 :user/name "josh" :friend/id 2}
 {:user/id 1 :user/name "josh" :friend/id 3}
 {:user/id 1 :user/name "josh" :comment/id 1 :comment/text "hi there"}
 {:user/id 1 :user/name "josh" :comment/id 2 :comment/text "hi there again"}]
This would allow for quick queries and transforms to be written using only core functions. We don't usually have heterogeneous maps like these in the same list, but it's OK if there's enough in there to differentiate each subset. Figuring out a primary key is an interesting angle. For instance, what is the primary key of the last map above? :user/id or :comment/id? They are both part of the unique identification of the record. We could make a composite key, but having both individual keys is helpful because it helps us reference other data. We tend to not get confused because each key/value pair is more information about the entity, in this case one user's comment. We can add more key/value pairs related to that entity and the map only gets richer. Also, while the above format is good for querying and aggregation, it's not a very friendly data structure to send to someone outside your program. We tend to have things flatter for internal data (or data that only our own clients, like a UI, are going to use) and something with one or two levels of nesting for outside consumers.