OK, OK, we all know this, right? This is why we have database migrations, because our models (for me, this roughly means “database-persisted instances of some kind of in-memory object”, but you can interpret it more widely if that’s useful for you) change through time. We didn’t know we needed to track whether a Frobble is published, but now we do! So we add a column. Our code and our logic exists through time, so of course we need to change our DB model through time, too.

But today, a conversation with a client helped me realize a different facet of this, one that I think will help in future conversations with clients as we hash out what their data model actually is: a particular model will often have its own lifecycle, going from egg to larva to pupa to imago. The database probably cannot express all the constraints needed for these stages.

Imagine a blog post: let’s say it absolutely needs a title, it’s incoherent to have a finished blog post without one. Well, the key there is “finished”. When the blog post is still a draft, it probably can lack a title. So you have to mark the title as nullable or blankable in the database, right?

What’s important about this is that it helps me clarify language to use with clients. Instead of asking “is this field required?” I can ask “is there ever a time in the lifecycle of this entity where this field might be blank or missing?” To someone not thinking in database-terms, it’s really easy for “required” to mean “required for the final lifecycle stage” instead of “required at all lifecycle stages”.

And so, bit by bit, I improve my vocabulary.