datascript

Immutable database and Datalog query engine for Clojure, ClojureScript and JS
tianshu 2019-12-16T07:35:11.004600Z

Hi, folks. I'm new to DataScript, there's one confuse me while learning. I saw :db/id is used at entity-id and all the relations are built upon this. But in some case, the data from server (backed by sql) often looks like :user/id, that is not a global unique id. And this user/id is used for relationship. How can I simplify here?

cjsauer 2019-12-16T20:38:22.019500Z

@doglooksgood if I understand correctly, I’d believe you’d model this by using a schema like:

{:user/id {:db/unique :db.unique/identity}}
Now you can transact some users:
(d/transact! conn [{:user/id 123}, {:user/id 789}])
Later, if you need to build relations on user 123, you can do so using lookup refs. For example, let’s say we have a :user/best-friend relation, and user 123’s best friend is user 789:
(d/transact! conn [{:user/id 123, :user/best-friend [:user/id 789]}])
Notice how you don’t actually need to use raw :db/id in order to specify which entities you’re interested in; you can use their unique attributes instead. Keep in mind that :db/id itself is not globally unique either. It’s an entity id that is local to a specific DataScript database. It’s up to you to design a schema that includes such an attribute. In the example above, you could transact UUIDs as the values for the :user/id attribute if global uniqueness is a requirement. Hope this helps.

cjsauer 2019-12-16T21:02:13.025Z

Also, it is not recommended to set the :db/id yourself, as it can be seen as an internal implementation detail of the database. Further, for modeling the relations of “external systems”, I like to use namespaced keyword attributes that include that system name in the namespace part. For example: :facebook.user/id, :twitter.user/id, etc, Users in your system can then possess any combination of these unique attributes.