Consider, please this setup for a database backed application.
( in my case DB is MySQL and app is in Ruby ( Rails 3), but I don’t think it matters for this question)
Let’s say I have an app for a warehouse.
I have multiple items that would have categories and statuses.
For example table that has parts would have a few statuses such as: in stock, discontinued, backordered and multiple categories, such as: it hardware, automotive, medical, etc.
Also I have other tables that need statuses and categories, such as
Vendor: approved, out of business, new
Order: Open, processes, shipped, canceled.
Etc.
Here is the question:
I think if I wanted to properly normalize my db – I would have a table called categories, categories_types, statuses, statuses_types.
Then I would store all categories in that table, and any category that is of a certain type, such all categories of parts, would have a foreign key to category_type – parts, and so on. Same for types.
This is the normalized way.
However I often see that people create separate tables for specific categories, for example,
there would be a table called part_categories, vendor_categories, order_statuses, part_status. This is a less normalized db, but I guess when you are dealing with a lot of tables, it might be clearer.
Which of this approaches is a better one? What are the cons & pros in your experience?
I usually go with the first setup, but I see the second one so often that I’m beginning to doubt my approach.
Thank you.
In my experience, tables of enumerated names invariably evolve into their own full-fledged model eventually. Typically, it begins by adding boolean flags, or as mentioned in the answer above, referent types or valid date ranges.
From a relational perspective, neither approach – putting all status enums in one table, or breaking them into separate tables – is “more” normalized than the other. But from a type-theoretic standpoint, it makes more sense to put part_categories and vendor_categories in their own separate tables, for no other reason than it requires no code in the model to make sure you don’t accidentally associate a vendor category with a part.
If you do end up putting them all in the same table, Rails has a nice feature called polymorphic associations that will automate the type and the id columns for you. It’s a reasonable compromise between the two approaches.
Most importantly, I would contend that the enums will eventually take on a model life of their own, in which case you have a very messy job of finding all of them in the various tables, and recasting them in their own table. Tables are cheap; why be frugal with them?