Three Ways to Store an Enum, and a Trap Hiding in the Fastest One

Storing an enum as a mapping table, a string, or a plain number, the real cost of each, and the silent data corruption waiting inside the fastest option.

September 1, 20262 min read24 / 25

Every relationship in this design is settled. The only thing left is telling the ORM how to store an enum.

Three Ways to Store the Same Enum

An enum like a seat's status, available, booked, locked, can be stored in a database in one of three ways.

  1. A mapping table, a separate table pairing an ID with each enum value's name. This is the most correct option, since renaming a value only ever touches one row, and there's nothing to type incorrectly at the point of use.
  2. A plain string, storing the value's actual name directly in the column. Simple to read, but it costs more storage than a number needs to, and it opens the door to a typo turning into a silently invalid value.
  3. A plain number, storing each value's position in the enum: 0 for the first value, 1 for the second, and so on. The smallest and fastest of the three, and the option good enough for a machine-coding interview.

The Trap Hiding in the Fastest Option

⚠️ Storing an enum by position only stays safe as long as nothing about that enum's declared order ever changes. Insert a new value in the middle of the list, or delete one, and every position number after that point silently means something different than it used to. Existing rows don't get flagged or updated. They just start meaning the wrong thing, with nothing about the database complaining.

That risk is exactly why a mapping table is the right call for real production code, even though it takes more setup than a plain number does. For a machine-coding round, the position-based number is a reasonable shortcut, as long as it's a conscious trade-off and not an accident.

Telling the ORM Which Option to Use

The mechanism is the same regardless of which of the three gets picked: mark the enum field so the ORM knows to treat it as an enum in the first place, and tell it whether to store the position or the name. Getting that annotation wrong, or skipping it, is what silently produces whichever of the three trade-offs above wasn't actually intended.

One extra wrinkle shows up the moment the field is a list of enum values instead of a single one, like Auditorium's list of supported features. The ORM needs a second, separate signal for that, telling it this isn't one value but a whole collection of them stored together. Without it, the ORM has no idea a list of enums should be treated any differently from a single one.