Fork me on GitHub
#datomic
<
2023-11-21
>
indy14:11:00

Everytime I data model in datomic, there is a conflict on whether to use generic attributes or specific attributes. I've gone through the documentation multiple times but there is no advice on this. Are there any guiding principles that you use that you've developed from experience?

ghadi14:11:11

I believe I understand you, but what is an example of this generic vs. specific attr?

indy14:11:42

Say, for example, there are posts and I want to add the ability to vote (upvote and downvote) for it. Should I have a generic entity like this:

{:vote/type :vote.type/up 
:vote/parent [:post/id "some-post-id"]
:vote/created-by [:user/id "some-user-id"]}
or a specific entity like this?
{:post.vote/type :post.vote.type/up
:post.vote/parent [:post/id "some-post-id"]
:post.vote/created-by [:user/id "some-user-id"]}

indy14:11:49

My actual scenario now is that I have a slider that allows choosing a number from 1-10 and it's associated to only one kind of entity atm, call it an issue entity. Should I use generic attrs that allow building a generic number voting entity, say like vote/score or should I have a specific issue.severity.vote/score attr?

favila15:11:09

I think specific should always be the default in everything. Generality comes later and must be carefully planned

favila15:11:25

The number of times I’ve been burned by premature abstraction for a feature that never gets built. Don’t design yourself into a corner, but also don’t assume you know exactly what general abstraction will eventually be the one you need

favila15:11:49

So if you know for sure you’re going to have a general voting system and know what’s the same and what’s different, go ahead and design that system. Otherwise default to solving the problem in front of you and figure out the generality later

ghadi15:11:50

that being said, if you have an attribute that has global semantics no matter what entity it's on, by all means make it a general attribute

ghadi15:11:06

like an attribute :list/ordinal

👍 1
favila15:11:21

You can always use other abstractions (such as rules) to make specific things conform to a more general interface you make later

favila15:11:00

+1 to ghadi’s point. Some systems are designed for their generality and you should establish those on day one of your db. Things like: how will I “type” entities, how will I determine existence and non-existence, what tx metadata will I use, how will I handle order and repositioning, etc

favila15:11:07

Also id systems

favila15:11:36

But these are more data-model concerns I think, and are pretty closely tied to the specific db tech you are using, and are driven by the strengths and constraints of your db. But for the domain model, default to specificity, because the generality is harder to know until you do literally have two of them

👍 1
indy15:11:57

Thanks @U050ECB92 and @U09R86PA4. I default to specificity very much when it comes to code and then wait for patterns to emerge to create an abstraction but that’s in code. Just wanted to know if the same applies to datomic too from the experienced (since I’m new to datomic). There is this feeling I gather from datomic documentation that the schema should be carefully planned and planned for accretion which often puts me under pressure to design carefully. I’ll stick to specificity when in times of doubt then.

ghadi14:11:10

you're absolutely correct that schema has more pressure to design carefully.... good luck! simple_smile

ghadi14:11:55

one thing I do is make a spreadsheet of use-cases and the queries / transactions / indices that will fulfill them

ghadi14:11:18

and I try to describe things with as much precision as possible

ghadi14:11:32

schema is inert, it has to be animated by queries and transactions

ghadi14:11:58

e.g. looking at schema doesn't tell you if an attribute is born at the same time as the entity is born, or if it comes later