In a relational DB, I could have a table Person
and a table Hobby
. Every person can have zero, one or more hobbies, and I also want to record, say, the priority of those hobbies for every person.
I could create a relationship table with the 2 foreign keys PersonFK
and HobbyFK
, and one plain column Priority
.
In datomic, to model a simple n:m relationship (without the priority), I'd probably create an attribute of type Reference
with cardinality Many
, that I'd use for Person
entities.
But how would I go about qualifying that relation to be able to store the priority? Would it have to be done analogously to the relational case, i.e. by creating a new entity type just for that relation? Or is there any better way? Using some meta data facility or something?
A similar question was asked on the Datomic mailing list a few days ago:
https://groups.google.com/d/topic/datomic/7uOl-TISdxA/discussion
In summary, the answer given there is that you are right: you need to create a relation entity on which to store the extra information.
The accepted answer here is now no longer the full story, given a new feature added to Datomic in June 2019. Sometimes you will still want to reify the relationship, but there is also now another option: heterogenous tuples
An attribute value, i.e. the v
in the eavto
5-tuple, can now itself be a tuple.
This is a clojure vector of max length 8. This isn't a way to store an arbitrary amount of meta-data on the relationship, due to max length 8.
Official blog post announcement.
Discussion of the release on twitter.
In your case:
{:db/ident :person/hobby
:db/valueType :db.type/tuple
:db/tupleTypes [:db.type/ref :db.type/long] ; hobby, priority
:db/cardinality :db.cardinality/many}
To use this in datalog, you can use the tuple and untuple functions.
It may be best though to use such tuples like arrays, where a tuple really represents compound data. Indeed the example in the docs supposedly for these heterogeneous tuples actually uses homogeneous data, so I think it's really up to the user of datomic what to make of these choices.
In the sql world, generally if data is of different types it's probably not a good idea to treat it like an array, due, for starters, to the loss of power you'll get when manipulating those data structures from the query language. Datomic might not be completely equivalent, being as it is a graph database, and perhaps this is still relatively uncharted territory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With