To design a schema for your invoice system where you have both Customers and Vendors with similar attributes, you have a couple of options. Here are two common approaches:
Option 1: Separate Tables for Customers and Vendors
In this approach, you maintain separate tables for Customers and Vendors. This is straightforward and keeps the data logically separated.
Schema Design
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
number VARCHAR(50),
tax_number VARCHAR(50),
address TEXT
);
CREATE TABLE vendors (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
number VARCHAR(50),
tax_number VARCHAR(50),
address TEXT
);
CREATE TABLE invoices (
id INT AUTO_INCREMENT PRIMARY KEY,
type ENUM('sale', 'purchase') NOT NULL,
customer_id INT,
vendor_id INT,
amount DECIMAL(10, 2) NOT NULL,
date DATE NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers(id),
FOREIGN KEY (vendor_id) REFERENCES vendors(id)
);
Explanation
-
customerstable stores customer-specific information. -
vendorstable stores vendor-specific information. -
invoicestable has atypecolumn to distinguish between sale and purchase invoices, and foreign keys to eithercustomer_idorvendor_id.
Option 2: Single Table for Both Customers and Vendors
In this approach, you use a single table to store both Customers and Vendors, and add a column to distinguish between them.
Schema Design
CREATE TABLE parties (
id INT AUTO_INCREMENT PRIMARY KEY,
type ENUM('customer', 'vendor') NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
number VARCHAR(50),
tax_number VARCHAR(50),
address TEXT
);
CREATE TABLE invoices (
id INT AUTO_INCREMENT PRIMARY KEY,
type ENUM('sale', 'purchase') NOT NULL,
party_id INT,
amount DECIMAL(10, 2) NOT NULL,
date DATE NOT NULL,
FOREIGN KEY (party_id) REFERENCES parties(id)
);
Explanation
-
partiestable stores both customers and vendors, distinguished by thetypecolumn. -
invoicestable has atypecolumn to distinguish between sale and purchase invoices, and a foreign key toparty_id.
Which Option to Choose?
- Option 1 is more straightforward and keeps the data logically separated, which can be easier to manage and understand.
- Option 2 reduces redundancy and can simplify queries if you often need to treat customers and vendors similarly.
Choose the option that best fits your application's requirements and complexity. If you expect the attributes of customers and vendors to diverge in the future, Option 1 might be more flexible. If you want to keep things simple and DRY (Don't Repeat Yourself), Option 2 might be more suitable.