Here is a simple example:
Assume I have a customer table that has a one-to-many relationship with the address table (a customer can have multiple shipping addresses but a shipping address can only belong to a single customer).
Customer Table
-------------
customer_id (PK)
Address Table
-------------
address_id (PK)
customer_id (FK)
Now I want each customer to be able to specify a default shipping address.
I can think of 2 ways but both have drawbacks.
Option 1
Add a Boolean column to the Address Table called “is_default”.
Pros
- Select queries are simple
- Straightforward for other people to understand if they see the DB model
Cons
- The application is forced to enforce and maintain the “only one row can be a default” constraint.
- Updating the default field is a pain because it requires the application to check and reset the previous default option.
Option 2
Add a column to the Customer table called “address_id” and make it a foreign key (also allow nulls just in case no address exists).
Pros
- Easy to update the default address if the user decides to change it.
- Database maintains the “only one row can be a default” constraint.
Cons
-
I have to add a new indexed column to the Customers Table every time I decide to add some kind of default metadata.
-
Seems like a hack
My question is, is there a standard way to handle this kind of scenario that I am overlooking? Of course there are other options (maybe creating an EAV default options table?) but I’d prefer to keep it as simple as possible because the change is being made to an existing code base so I don’t want to break anything.
I would do this, especially if you’re worried about breaking existing code.
Isn’t that tidy? By pulling the whole thing into a separate table, you leave the existing tables alone. If you’re using some kind of ORM layer, the object over this new table can be queried for directly, and then you can walk to the Address object. No need to even introduce the new object to the existing Customer or Address objects.