Designing a schema
Normalise until it hurts, denormalise until it works - and pick types deliberately.
Open this lesson in the learning hubKey points
- Store each fact once. A city name repeated in a thousand rows is a thousand places to update.
- Foreign keys make the relationship explicit and let the database reject orphan rows.
- Choose the narrowest type that fits:
INToverBIGINT,DATEoverDATETIMEwhen there is no time. - Use
DECIMALfor money, neverFLOAT- binary floating point cannot hold 0.10 exactly. - Denormalise only when a measured query is too slow, and accept you now maintain two copies.
Example
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(120) NOT NULL,
city VARCHAR(80) NOT NULL,
joined DATE NOT NULL
) ENGINE=InnoDB;
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
product VARCHAR(120) NOT NULL,
amount DECIMAL(10,2) NOT NULL, -- money: never FLOAT
status ENUM('pending','shipped','cancelled') NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers(id)
) ENGINE=InnoDB;
Constraints are the last line of defence: application code can forget, the database cannot.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the MySQL Course course, and every lesson in it is listed on the MySQL Course contents page.