In a database where users can place orders, is it better to have a new table with addresses or each order has the address data in its header.
This is not just about users (and their addresses) but also about prices and other information about products you are selling, that can change after the order has been placed, yet the order itself must remain intact.
Generally, there are 2 approaches to this:
(1) is the more "practical" approach, but can lead to data redundancies (e.g. when address doesn't change, you are nonetheless making separate copies of it).
(2) is the more "purist" approach, but may require more JOINing and generally be more complex.
In general you will most likely want to separate:
This is because users can change address over time, but old addresses need to be kept because they have orders against them. Plus a single user can have multiple orders from the same address, so we separate out this information to reduce duplication.
http://en.wikipedia.org/wiki/Database_normalization
i can't think of any reason for an address to be in the same table as an order except that it saves you a small amount of work now.
arguments for having a separate table include:
being able to associate multiple delivery addresses with a user without having to search through all orders (so it's easy to offer users a drop-down list of addresses they have previously used).
you can use the same table for billing and delivery addresses, avoiding duplication
you can extend/change how addresses are stored in future (eg by adding a country field when you go international) without having to update every order.
none of this is much related to optimization. not sure why that is in the title?
[Branko has a good point about preserving order data. however, you don't need to make the database completely versioned. you can simply have an "expired" flag on things that are referenced from the orders (like users and addresses) but which no longer have current values. in other words you only need two "versions" - current and historical. as long as you make references in the order table explicit (so you don't go to the delivery address via the user, but instead link directly to the address table from the order table, that can be made to work. fully versioning a database, including relationships, is a lot of work.]
Don't reinvent the wheel. Order systems have been around for ages and best practices are well established. You can create an address book so that your contacts can have multiple addresses. Contact has zero-to-many Addresses. However, when it comes time to ship, do persist a copy of the address with the Order (or Shipment entity). It's important to store the address as point-in-time data in the order to maintain accurate historical data. Magento, Shopify, Quickbooks all the major accounting and eCommerce systems have a model like this. One exception is Saasu accounting. They do not persist the address with the order, so you have to create a new contact for each order, otherwise if you ever modify a customer address, you end up re-writing the address on historical orders. A really terrible design!