
CREATE DATABASE
CREATE DATABASE
FOREIGN KEY
FOREIGN KEY
GROUP BY
GROUP BY
INNER JOIN
INNER JOIN
LEFT JOIN
LEFT JOIN
When you start working with databases, MySQL is usually the first system you'll encounter. It's battle-tested and powers everything from small side projects to massive enterprise applications.
Instead of reading a massive textbook, this guide covers the 20% of commands you'll use 80% of the time!
Analyze queries for sargability, missing composite indexes & offsets
Analyze SQL queries for performance anti-patterns, wildcards, and slow offsets. Generates optimized queries and DDL composite indexes for PostgreSQL, MySQL, and SQLite.
Don't have MySQL installed? Spin it up instantly using Docker:
docker run --name mysql-dev -e MYSQL_ROOT_PASSWORD=secret -d mysql
Connect via terminal with mysql -u root -p.
Create and select a database:
CREATE DATABASE zoo_db;
USE zoo_db;
Use Foreign Keys to ensure data integrity!
CREATE TABLE habitat (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64));
CREATE TABLE animal (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(64),
habitat_id INT,
FOREIGN KEY (habitat_id) REFERENCES habitat(id)
);
What is the purpose of a FOREIGN KEY constraint?
| Operation | Syntax | Key Point |
|---|---|---|
| INSERT | INSERT INTO table (col) VALUES (val) | Auto-increment ID handled automatically |
| UPDATE | UPDATE table SET col=val WHERE condition | ALWAYS use WHERE clause! |
| DELETE | DELETE FROM table WHERE condition | Without WHERE = delete all rows! |
| SELECT | SELECT col1, col2 FROM table WHERE condition | * = all columns (avoid in production) |
INSERT INTO habitat (name) VALUES ('River'), ('Forest');
UPDATE animal SET name = 'Quack' WHERE id = 2;
DELETE FROM animal WHERE id = 1;
If you run an UPDATE or DELETE command without a WHERE clause, you will modify or delete every single row in the table. Always double-check your queries!
What happens if you run `UPDATE animal SET name='Test';` without a WHERE clause?
| Clause | Purpose | Example |
|---|---|---|
| SELECT | Columns to return | species, AVG(age) |
| WHERE | Filter rows BEFORE grouping | WHERE id != 3 |
| GROUP BY | Group rows by column | GROUP BY species |
| HAVING | Filter groups AFTER aggregation | HAVING AVG(age) > 3 |
| ORDER BY | Sort final result | ORDER BY AVG(age) DESC |
Want to find the average age of each animal species?
SELECT species, AVG(age) as average_age
FROM animal
WHERE id != 3
GROUP BY species
HAVING AVG(age) > 3
ORDER BY AVG(age) DESC;
This powerful query filters, groups, aggregates, filters the groups, and sorts the final result!
| Join Type | Result | Use When |
|---|---|---|
| INNER JOIN | Only matching rows from both | Required relationships |
| LEFT JOIN | All left + matched right (NULL if no match) | Optional relationships |
| RIGHT JOIN | All right + matched left (NULL if no match) | Rarely used (flip tables instead) |
| CROSS JOIN | Cartesian product (all combinations) | Generating test data |
To combine data from our two tables and view the animal's name alongside its habitat's name:
SELECT animal.name AS animal_name, habitat.name AS habitat_name
FROM animal
INNER JOIN habitat ON animal.habitat_id = habitat.id;
Which JOIN returns all rows from the left table and NULLs for non-matching right table columns?
Mastering MySQL requires muscle memory. Open up your terminal and practice creating tables and joining data until it becomes second nature!
Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.

Master modern database sharding architectures: horizontal partitioning, range vs consistent hash keys, cross-shard joins, distributed transactions (2PC vs Saga), Vitess, and Citus.
Read more
Real-time analytics benchmark comparing ClickHouse vs Snowflake: P95 query latencies, compression ratios, compute costs, and when to migrate from cloud warehouses.
Read more
Building real-time event analytics with ClickHouse Materialized Views and ReplacingMergeTree: deduplication patterns and sub-second aggregation queries.
Read more