Don't Confuse a Brand With the Actual Entity

Why Theatre to Auditorium is settled just by looking at the class shape, the real mistake behind guessing Theatre to City is many-to-many, and why Ticket to Seat is the first genuinely many-to-many relationship in this design.

September 1, 20263 min read23 / 25

A mapping table isn't a trick for turning a many-to-many relationship into something simpler. It's the only way to represent one at all, since a plain foreign key column can only ever point at one row, never a list of them.

Theatre to Auditorium: The List Already Answers Half the Question

Theatre holds a list of Auditorium objects, and that alone settles one direction immediately. If a class holds a list, "one" can never be the answer on that side. One theatre has many auditoriums, full stop, the class itself already says so.

The other direction is straightforward too: one auditorium belongs to exactly one theatre. One-to-many.

Don't Confuse a Brand With the Actual Entity

Theatre to City looks like it should follow the same easy pattern, and one specific mistake keeps showing up here: guessing many-to-many because a chain like PVR clearly operates in more than one city.

That's true of the brand. It isn't true of one specific theatre. The entity in this design is a single physical building, one particular PVR branch, not the franchise name shared across hundreds of them. That one building sits in exactly one city, even though the brand it operates under shows up all over the country.

Once the brand and the actual entity are pulled apart, the answer is the one already used for Show to Auditorium and Show to Movie: one theatre has one city, one city has many theatres. Many-to-one.

Ticket to Seat: The Direction That Actually Gets Tricky

Ticket holds a list of Seat objects, since a single booking can cover more than one seat. Same rule as before: a list rules out "one" immediately, so one ticket relates to many seats.

The reverse direction is where this stops being easy. How many tickets can one seat belong to? A refund changes what the honest answer to that actually is.

The Answer: Ticket to Seat Is Genuinely Many-to-Many

One seat can belong to more than one ticket, for two separate reasons. A ticket for that seat might get refunded and cancelled, and a fresh ticket later booked for the exact same seat, both tickets still sitting in the database. And the same physical seat gets its own ticket for every different show it's ever booked for: tomorrow's show, the day after's show, each one its own ticket.

One ticket has many seats, and one seat can belong to many tickets. This is the first genuinely many-to-many relationship between two real entities in this whole design, not a mapping class standing in for one.

A natural objection shows up here: every ticket already points at exactly one show, so shouldn't that pin a seat down to one ticket per show, at least? No — a cardinality is always evaluated directly between the two entities actually in question, never routed through a third one. The question is Ticket to Seat, full stop, not Ticket to Show to Seat. The same physical seat still ends up with its own separate ticket for every different show it's ever been part of, which is exactly what makes the direct Ticket-Seat relationship many-to-many, regardless of what any single ticket's own relationship to one show looks like.

Three More, Settled Quickly

The rest of Ticket's relationships follow the same two questions:

  1. Ticket to User. One ticket is booked by one user. One user can book many tickets. Many-to-one.
  2. Ticket to Show. One ticket is for one show. One show has many tickets. Many-to-one.
  3. Ticket to Payment. One ticket holds a list of payments, so one ticket can have many. But one payment is only ever made for one ticket. BookMyShow doesn't let a single payment cover more than one booking at a time. One-to-many, not many-to-many — worth noticing precisely because it looks like it should match the Ticket-Seat pattern, and it doesn't.

This isn't specific to booking movie tickets either. Ticket is really playing the same role an Order plays on any e-commerce platform, and an order-to-payment relationship comes out one-to-many there for the identical reason: a platform that lets one order span several products still processes one payment per order, not one payment shared across several orders.

User turns out to need no non-primitive attributes at all, which closes out every relationship in this design.