This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-07-18
Channels
- # announcements (4)
- # aws (24)
- # babashka (118)
- # babashka-sci-dev (18)
- # beginners (56)
- # calva (2)
- # clojure (54)
- # clojure-dev (8)
- # clojure-europe (25)
- # clojure-gamedev (5)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (2)
- # conjure (1)
- # core-async (1)
- # data-science (3)
- # datomic (5)
- # emacs (8)
- # fulcro (4)
- # hyperfiddle (12)
- # interop (1)
- # jackdaw (4)
- # lsp (5)
- # mid-cities-meetup (5)
- # nbb (32)
- # off-topic (21)
- # reitit (5)
- # shadow-cljs (12)
- # sql (8)
- # vim (18)
- # xtdb (9)
Are there any recommendations somewhere about modelling multi-tenant data? Should we have a single tenant reference attribute, which is used on every kind of entity or should we have a ref attribute for every "entity-type"? eg:
{:tenant/ref [:tenant/uniq-id 123] :user/id 345}
{:tenant/ref [:tenant/uniq-id 123] :frob/id 678}
vs
{:user/tenant [:tenant/uniq-id 123] :user/id 345}
{:frob/tenant [:tenant/uniq-id 123] :frob/id 678}
the 1st solution would allow using a single, common and also simple datalog :where
clause or rule, to limit queries to a specific tenant, so it feels less error-prone.
the 2nd solution allows operating on the whole collection of entity-types for a specific tenant, by simply using pull expressions, with a reverse lookup ref, eg. (d/pull db-val-for-all-tenants [:frob/_tenant ['*]] [:tenant/uniq-id 123])
, which would return all frobs of tenant 123.
if i have a single :tenant/ref
, i would always need to write datalog queries, for operations, which would be effectively just simple pulls, then i would also need to unwrap them from the resulting, single element vectors, since there is no find-scalar
option for Datomic Cloud (https://docs.datomic.com/cloud/query/query-data-reference.html#arg-grammar):
find-spec = ':find' find-rel
find-rel = find-elem+
find-elem = (variable | pull-expr | aggregate)
like for Datomic On-Prem (https://docs.datomic.com/on-prem/query/query.html#query):
find-spec = ':find' (find-rel | find-coll | find-tuple | find-scalar)
find-scalar = find-elem '.'
find-elem = (variable | pull-expr | aggregate)
This talks mentions how filtered databases on Datomic On-Prem, combined with recursive datalog rules can safeguard per-tenant information retrieval: https://youtu.be/7lm3K8zVOdY?t=919 we would like achieve the same with Datomic Cloud, but it's unclear how.
forgot to mention that in the above examples, that those :user/id
and :frob/id
are IDs of 3rd-party systems, so I also had to use a composite key, with a unique constraint, like this:
{:user/id 345
:user/tenant+id ["tenant-123" 345]
:tenant/ref {:db/id "tenant-123"
:tenant/uniq-id 123}}
to keep 3rd-party data from multiple tenants within the same DB.