Mysql – Is this correct normalization for the tables

database-designMySQLPHP

I think I'm confusing myself and making this too complicated. At this point, I need outside advice.

I have a Laravel 7 application where a user will enter orders. Each order has one customer. Each order has one contact. Each customer has many contacts, but contacts only belong to one customer.

When the user is entering the order and chooses a customer, another select field populates with contacts associated with that customer.

Here is my structure:

orders table:
id
customer_id
contact_id

Customers table:
id
name

Contacts table:
id
customer_id

Is this good or do I need to change the structure? I'm having trouble setting up the relationships in Laravel.

Best Answer

I'm not familiar enough with Laravel 7 to understand how well it implements alternate keys/composite keys, but this is basically what you've described: enter image description here

Notes:

  1. The alternate keys are crucial as an Id in and of itself does not provide uniqueness as required by the Relational Model. If I can spam "Customer 1, Dwayne Johnson" a million times into Contact then no key exists and there is a normalization error.
  2. The composite key (CustomerId, ContactId) is required to ensure CustomerId is migrated properly to Order
  3. IE is inversion entry, or non-unique index. This allows orders to be quickly searched by customer.
  4. ContactId itself is not unique. If you are using a ORM that requires an Id column on everything, you would need to make the relationship between Customer and Contact non-identifying. In doing so you will remove the ability to retrieve a customer's orders without joining to Contact first. Under no circumstances should you create a relation between Customer and Order as the Contact selected must belong to the Customer in question and this would introduce a normalization error.

Revised model based on comment:

enter image description here