The Limit of 'You Can Already Get There'

Why a schema can never enforce a business rule about how many rows should exist, and the exact point where a chain of relationships stops pointing at one specific thing.

August 31, 20262 min read15 / 25

Two sharp questions surfaced once this design actually started turning into a running application, and both are worth sitting with directly.

A Schema Can't Enforce What Only a Service Knows

Here's the first one: when a new show gets created for an auditorium, something has to make sure every seat in that auditorium gets its own ShowSeat row. Can the schema itself guarantee that happens?

No. A schema describes structure: what columns exist, what a foreign key points at, what values a status can hold.

It has no way to express "create one row per seat in this auditorium," because that's not a structural rule, it's a business rule, triggered by an action. Something else has to actually do that work.

That something is a service. A createShow operation takes a movie, an auditorium, a start time, and an end time from whoever's creating the show, and its own logic is what loops through every seat that auditorium has and creates a ShowSeat row for each one.

The schema only knows what a row looks like once it exists. Deciding how many rows should exist, and when, belongs entirely to the code that creates them.

The Limit of "You Can Already Get There"

The second question cuts right at a rule this series has leaned on repeatedly: don't duplicate a relationship you can already reach through another one. Show doesn't need its own theatre reference, because Auditorium already leads there.

So here's the sharp version of that same instinct, aimed at ShowSeat: since Show has an Auditorium, and an Auditorium has its seats, does ShowSeat even need its own direct reference to Seat? Could it just hold show and status, and reach the seat through that same chain?

No, and the reason exposes exactly where that earlier shortcut stops working. An auditorium doesn't have one seat, it has hundreds. Following Show → Auditorium gets you to the entire set of seats in that room, never to which one of them a particular status actually belongs to.

Show leads to Auditorium leads to many seats, but that chain only ever points at the whole set. ShowSeat still needs its own direct reference to one exact seat ExpandShow leads to Auditorium leads to many seats, but that chain only ever points at the whole set. ShowSeat still needs its own direct reference to one exact seat

The shortcut of "just follow the chain instead of duplicating the reference" only holds as long as the chain resolves to exactly one thing. The moment a chain passes through a one-to-many relationship, like an auditorium's list of seats, it stops pointing at a single answer, and whatever's on the other end needs its own direct reference again. ShowSeat genuinely does need show, seat, and status, all three, because there's no path through the rest of the model that narrows a hundred seats down to the one this particular row is actually about.