Currently our database is set up so that a payment transactions records a payment type ID, and this links to a payment type (cash, check, credit) table that contains these values. Example:
Payment Transaction:
- ID
- Amount
- Date
- Payment Type ID
Payment Type:
- ID
- Payment Type (Cash, Credit)
My question is whether or not I should just remove the payment type table, and just store the payment type value as text inside the payment transaction.
This is similar to this question. except with payment types it’s pretty certain that no new information will ever need to be add data per payment type. ‘Cash’ doesn’t link to anything, there’s nothing I need to know about Cash itself, it just is.
As far as I can tell the pros and cons would of replacing the payment type table with a single field would be:
Pros
- Removes a mostly unnecessary join whenever the payment type needs to be found.
- The payment type for a transaction will always accurately reflect what it was at the time the transaction was recorded. i.e. If I change the ‘Cash’ record in the payment types table to ‘Credit’ (for whatever reason), all payment transactions that link to Cash will now be linked to Credit.
Cons
- Storing the payment type as a text field will slow down sorting by payment type, and make such a sort somewhat messier than it is now.
- The payment type for a transaction will always accurately reflect what it was at the time the transaction was recorded. i.e. If I had a typo and the payment type was stored as ‘Kash’, I could easily fix that typo and all transactions that link to that payment type will automatically be updated.
I’m leaning towards removing the payment type table and adding the single field to the payment transaction table, what do you recommend would be the best course of action?
I don’t agree with either of your pro arguments.
There’s just your assumption that this will be a performance bottleneck. Denormalization is something you should do when you have data that says you must. This isn’t one of those times.
You should not allow someone to modify the payment type this way. Changing the payment type should be another transaction, with its own timestamp.
Any relational database can handle the JOIN and the normalized tables. You’re guilty of premature optimization, I fear.
I’d spend less time worrying about this and more time thinking about how you’ll deal with history. How long will you keep transactions around before moving them out to a history table? Have you thought about partitioning your database by months according to timestamp? That would be more worthy of your efforts.