Question

Let's say we have a webshop, where people can save their shipping/billing addresses for later use. We store our data in a relational database, so obviously the addresses get their own table. When the customer makes a purchase, we want to record which address did he select for his purchase, so that he can later review it in his purchase history. We can create a foreign key in the purchase table to the address table, so that the DB stays somewhat normalized, but this way, we have to ensure that the addresses are immutable, so that the shipping/billing addresses in the purchase history stay the same. The other approach is to replicate the addresses in the purchase table, so that the user can freely edit/delete from the addresses' table, and the purchase history stays the same. This replication scheme works well for small amounts of data, but let's say we want to attach a photo to each shipping/billing address, and now it's becoming too expensive, especially on resource constrained devices like smartphones. Which approach is the better? Are there any other ways of dealing with this pattern?

Was it helpful?

Solution

To allow users manage their addresses, you'll need to store info for whether the address has been used in purchase (by checking the purchases table or a separate flag in the addresses table). The key part of the solution here is this flag or check in the database indicating that an address has been used in a purchase, as mentioned by @sqlvogel.

This one piece of info will allow the following scenarios:

  1. Letting the user enter a new address - will not have an existing reference in the purchases history, so can also be edited before purchase.
  2. Letting the user pick an existing address, which may or may not have been used in a previous purchase.
  3. Letting the user change the address for a purchase, either by editing a new and unused address or picking one of the previously used addresses.
  4. If a user edits an existing and used address, save it as a new address instead of editing the original (and a good idea to let them know/see that a new address has been added).

You can provide a pseudo-deletion feature by adding a flag to an address indicating that it's a historical record (which you should also allow your users to know).

Shipping vs Billing address id: You may already have done this but these two need to be separate columns in the purchase table. So history is kept accurately with the controls above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top