Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

qualified relationships in datomic

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?

like image 226
SuperHorst Avatar asked Sep 16 '12 03:09

SuperHorst


2 Answers

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.

like image 78
grahamstratton Avatar answered Oct 29 '22 16:10

grahamstratton


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.

like image 30
mwal Avatar answered Oct 29 '22 15:10

mwal