Fork me on GitHub

Bit unsure on how to setup my entities. There is a :crux.db/id that I set to something like (keyword "page" "generated-id") for example, but I also set :page/id to just "generated-id" , just in order to be able to query for all the pages (with [?page :page/id ?page-id]). I'm unsure if I should just get rid of the :page/id and use :crux.db/id directly, but it'll be harder to make sure the queries return only the things I want then, as I'd have to make sure the attributes are unique for that entity. Hope this makes sense and hope someone can make sense of it all 🙂


seems like you're using pathom? I do too and I make :crux.db/id a plain UUID and :foo/id an exact copy of :crux.db/id. if that's all right so far, then can you explain what you mean by "harder to make sure the queries return only the things I want then, as I'd have to make sure the attributes are unique for that entity"?


If you need to have multiple attributes unique you could encode them all in the ID using a map (you would also need to repeat them as normal attributes, in order to query). +1 for more explanation 🙂


I don't use pathom. The "harder to make queries' was if I remove the :foo/id that identifies what type of resource it is. For example, if I only use :crux.db/id , it's more complicated to make a query for "All page resources" for example. If I have a :page/id attribute, it's trivial. But feels like I'm duplicating things and there might be a better way of doing it


Might be something fundamental thing I'm missing here, as I'm new to crux/datalog stuff in general, so just starting out a few days ago


Maybe this illustrates what I'm wondering about better


Do all pages have a 'page/name' attribute?


In this case, yes. Trying to find an approach that works for all entities I have. In the case of a page, it also has :website/id which I use to link it together with a page (One website can have many pages), but the website itself also has a :website/id obviously.


Personally, I would discourage conflating an entity's identity (which remains constant over time) with its type (which may not). An individual entity may represent all of, for example, a prospective hire, an employee and a former employee. If you encode the type (and other attributes) into the identity then you'd have to rely on copying such entities to new identities (preserving linkages somehow). This feels to me to be unnecessary.


Hm, I'm not sure I understand exactly what you mean here. I don't think I am "encoding the type" into the identity, but I might just misunderstand


Crux supports both intensional and extensional typing. You can use an attribute that indicates explicit type ('entity/type' say), or you can implicitly determine the type as a function of the attribute names, for example, 'page/name'.


Aha, so setting something like :entity/type :page instead of :page/id , would actually make me able to get rid of the :page/id without losing the possibility to easily query for all pages

👍 3

By using a meaningful namespace (page) as your entity's identity, you are implicitly encoding the type. As @U899JBRPF suggests, it's ok to use a map as the entity identity, but attributes of that map should ideally relate to an entity's identity, nothing else.


I see. Thanks a lot for taking the time to explain, crux is still melting my brain a bit, after dealing with only relational/document databases for years

👍 3

Now, some people will argue benefits for encoding type into the namespace of the identity. As a purist, I find this introduces unneeded complexity.


Relational databases have tables, which are used as a pragmatic step to bootstrap relations. Document databases encode schema into the key in order to find documents (many don't have the benefit of Datalog). I suggest keeping the identity as opaque as possible (perhaps just a uuid) and leaning on Datalog to query your entities. The fact is that Crux indexes all top level attributes, so there are no performance advantages to looking up an entity by its key rather than by its attribute values.


Yup, I'll keep that in mind. That last part is good to know, I instinctively tried to use the key to do lookups in a lot of cases


Relax, let your brain melt and play with Crux. It does challenge some deeply help presumptions but the way Crux approaches data management is simpler (in our opinion) and takes a bit of getting used to!