🏗️ Lesson 4: Creating Databases & Tables
Time to build something. In this lesson you'll create your first database, define tables with columns, and learn to modify and delete structures — the foundation for everything that follows.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Create and drop databases with
CREATE DATABASEandDROP DATABASE - Create tables with columns using
CREATE TABLE - Modify existing tables with
ALTER TABLE(add, modify, rename, drop columns) - Rename and delete tables with
RENAME TABLEandDROP TABLE - Use
IF EXISTSandIF NOT EXISTSto write safe, repeatable SQL
Estimated Time: 45 minutes
Prerequisites: MySQL running, comfortable with CLI or phpMyAdmin (Lesson 3)
📑 In This Lesson
Creating and Managing Databases
A MySQL server can hold many databases, and each database holds many tables. Think of it like a filing cabinet: the server is the cabinet, each database is a drawer, and each table is a folder inside that drawer.
CREATE DATABASE
To create a new database:
CREATE DATABASE bookstore;
Output:
Query OK, 1 row affected (0.01 sec)
Verify it exists:
SHOW DATABASES;
You should see bookstore in the list alongside the system databases.
CREATE DATABASE IF NOT EXISTS
If you try to create a database that already exists, MySQL throws an error. To avoid this, use the IF NOT EXISTS clause:
-- Safe version — won't error if it already exists
CREATE DATABASE IF NOT EXISTS bookstore;
✅ Best Practice
Always use IF NOT EXISTS when creating databases (and tables). It makes your SQL scripts idempotent — safe to run multiple times without errors. This is especially important for setup scripts and deployment.
USE — Switch to Your Database
After creating a database, switch to it:
USE bookstore;
Output:
Database changed
Now all CREATE TABLE, SELECT, and other commands will operate inside bookstore.
DROP DATABASE
To permanently delete a database and all its tables and data:
DROP DATABASE bookstore;
⚠️ This Is Permanent!
DROP DATABASE immediately and permanently deletes the database and everything in it. There is no confirmation prompt, no undo, and no recycle bin. Always double-check before running this command, especially on a production server.
The safe version:
DROP DATABASE IF EXISTS bookstore;
Character Set and Collation
When creating a database, you can specify a character set (which characters can be stored) and collation (how those characters are sorted and compared). The modern default is utf8mb4, which supports all Unicode characters including emoji:
CREATE DATABASE IF NOT EXISTS bookstore
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
💡 utf8mb4 vs. utf8
MySQL's utf8 is actually a 3-byte subset that can't store emoji or some Asian characters. utf8mb4 is true 4-byte UTF-8. Always use utf8mb4 for new databases — it's been the default since MySQL 8.0.
Naming Conventions
Good names make databases easy to understand and maintain. Here are the conventions used by most professionals:
| Rule | Good Example | Bad Example |
|---|---|---|
| Use lowercase for everything | customers |
Customers, CUSTOMERS |
| Use snake_case for multi-word names | order_items |
orderItems, OrderItems |
| Table names should be plural nouns | books, categories |
book, category |
| Column names should be singular and descriptive | first_name, email |
fn, e, data1 |
| Primary keys named id | id |
bookID, pk_book |
| Foreign keys named referenced_table_id | customer_id |
custID, cust |
| Avoid reserved words as names | order_records |
order, select, table |
📖 Why Lowercase?
Table names are case-sensitive on Linux but case-insensitive on macOS and Windows. Using all lowercase avoids cross-platform bugs. It's also the industry standard for SQL identifiers.
💡 Tip: When in doubt, ask yourself: "If a new developer looked at this name, would they immediately understand what it holds?" If yes, it's a good name.
Creating Tables
The CREATE TABLE statement defines a new table — its name, its columns, and each column's data type. Here's the general syntax:
CREATE TABLE table_name (
column1 datatype [constraints],
column2 datatype [constraints],
column3 datatype [constraints],
...
);
Let's break this down with a real example:
CREATE TABLE books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author VARCHAR(100) NOT NULL,
price DECIMAL(8, 2) NOT NULL,
pages INT,
published DATE,
in_stock BOOLEAN DEFAULT TRUE
);
Here's what each part means:
| Column | Type | What It Means |
|---|---|---|
id |
INT AUTO_INCREMENT PRIMARY KEY |
Integer that auto-generates (1, 2, 3...) and uniquely identifies each row |
title |
VARCHAR(200) NOT NULL |
Variable-length text up to 200 characters; cannot be empty |
author |
VARCHAR(100) NOT NULL |
Variable-length text up to 100 characters; cannot be empty |
price |
DECIMAL(8, 2) NOT NULL |
Exact decimal number with up to 8 digits total and 2 after the decimal point (e.g., 999999.99) |
pages |
INT |
Integer; allows NULL (we might not know the page count) |
published |
DATE |
Date value (YYYY-MM-DD format); allows NULL |
in_stock |
BOOLEAN DEFAULT TRUE |
True/false value; defaults to TRUE if not specified |
💡 Data Types Preview
We'll cover data types in full detail in Lesson 5. For now, just know the basics: INT = whole number, VARCHAR(n) = variable-length text, DECIMAL(m,d) = exact decimal, DATE = date, BOOLEAN = true/false.
CREATE TABLE IF NOT EXISTS
Just like databases, you can guard against errors:
CREATE TABLE IF NOT EXISTS books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author VARCHAR(100) NOT NULL,
price DECIMAL(8, 2) NOT NULL
);
Understanding the Key Constraints
You saw a few keywords after the data types. Here's a quick reference — we'll explore these deeply in Lesson 5:
| Constraint | What It Does | Example |
|---|---|---|
PRIMARY KEY |
Uniquely identifies each row; cannot be NULL or duplicated | id INT PRIMARY KEY |
AUTO_INCREMENT |
Automatically assigns the next integer (1, 2, 3...) | id INT AUTO_INCREMENT |
NOT NULL |
Column cannot contain NULL (empty) values | title VARCHAR(200) NOT NULL |
DEFAULT |
Provides a value if none is specified during INSERT | in_stock BOOLEAN DEFAULT TRUE |
UNIQUE |
No two rows can have the same value in this column | email VARCHAR(100) UNIQUE |
Building Our Practice Database
Let's build a database we'll use throughout the rest of this course — an online bookstore. We'll start with three tables and expand them in later lessons.
📖 Follow Along!
Open your MySQL CLI (mysql -u root -p) and type each command as you read. Building the muscle memory of typing SQL is just as important as understanding the concepts.
Step 1: Create the Database
CREATE DATABASE IF NOT EXISTS bookstore
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE bookstore;
Step 2: Create the Books Table
CREATE TABLE IF NOT EXISTS books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author VARCHAR(100) NOT NULL,
price DECIMAL(8, 2) NOT NULL,
pages INT,
published DATE,
in_stock BOOLEAN DEFAULT TRUE
);
Step 3: Create the Customers Table
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
city VARCHAR(50),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Notice the new pieces:
UNIQUEonemail— no two customers can share the same email addressDATETIME DEFAULT CURRENT_TIMESTAMP— automatically records when the row was created
Step 4: Create the Categories Table
CREATE TABLE IF NOT EXISTS categories (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(255)
);
Step 5: Verify Your Work
-- List all tables in bookstore
SHOW TABLES;
-- Check each table's structure
DESCRIBE books;
DESCRIBE customers;
DESCRIBE categories;
Expected Output for SHOW TABLES:
+---------------------+
| Tables_in_bookstore |
+---------------------+
| books |
| categories |
| customers |
+---------------------+
3 rows in set (0.00 sec)
✅ You Just Built a Database!
Three tables, properly named, with appropriate data types and constraints. This bookstore database will be our playground for the rest of the course. We'll add data in Lesson 6, query it in Lessons 7–10, add relationships in Lessons 11–13, and much more.
Modifying Tables with ALTER TABLE
Requirements change. You'll often need to add new columns, rename existing ones, change data types, or remove columns that are no longer needed. The ALTER TABLE statement handles all of this.
ADD a Column
-- Add a 'phone' column to the customers table
ALTER TABLE customers
ADD COLUMN phone VARCHAR(20);
By default, the new column is added at the end. You can control placement:
-- Add 'phone' after the 'email' column
ALTER TABLE customers
ADD COLUMN phone VARCHAR(20) AFTER email;
-- Add a column at the very beginning
ALTER TABLE customers
ADD COLUMN member_id VARCHAR(10) FIRST;
MODIFY a Column (change its type or constraints)
-- Make 'phone' longer and require it
ALTER TABLE customers
MODIFY COLUMN phone VARCHAR(30) NOT NULL;
⚠️ Be Careful with MODIFY
If the table already has data, changing a column's type can fail or lose data. For example, you can't change a VARCHAR to an INT if the column contains text like "hello". Always check your data first.
RENAME a Column
-- Rename 'phone' to 'phone_number'
ALTER TABLE customers
RENAME COLUMN phone TO phone_number;
CHANGE a Column (rename + change type in one step)
-- Rename 'phone_number' to 'mobile' AND change its type
ALTER TABLE customers
CHANGE COLUMN phone_number mobile VARCHAR(25);
The difference between RENAME COLUMN and CHANGE COLUMN:
RENAME COLUMN— just renames (simpler, MySQL 8.0+)CHANGE COLUMN— renames AND lets you change the data type (works in all versions)
DROP a Column
-- Remove the 'mobile' column entirely
ALTER TABLE customers
DROP COLUMN mobile;
⚠️ Dropping Columns Is Permanent
Like DROP DATABASE, this is immediate and irreversible. All data in that column is gone.
Multiple Changes in One Statement
You can combine multiple alterations in a single ALTER TABLE:
ALTER TABLE books
ADD COLUMN isbn VARCHAR(13) UNIQUE AFTER id,
ADD COLUMN language VARCHAR(30) DEFAULT 'English',
MODIFY COLUMN pages INT UNSIGNED;
This is more efficient than running three separate ALTER TABLE commands because MySQL only rebuilds the table once.
ALTER TABLE Quick Reference
| Operation | Syntax |
|---|---|
| Add a column | ALTER TABLE t ADD COLUMN col TYPE; |
| Add a column at a position | ALTER TABLE t ADD COLUMN col TYPE AFTER other_col; |
| Modify a column's type | ALTER TABLE t MODIFY COLUMN col NEW_TYPE; |
| Rename a column | ALTER TABLE t RENAME COLUMN old TO new; |
| Rename + retype | ALTER TABLE t CHANGE COLUMN old new NEW_TYPE; |
| Drop a column | ALTER TABLE t DROP COLUMN col; |
| Rename the table | ALTER TABLE t RENAME TO new_name; |
Renaming and Dropping Tables
RENAME TABLE
-- Rename a table
RENAME TABLE categories TO genres;
-- Rename it back
RENAME TABLE genres TO categories;
You can also rename multiple tables in a single statement:
RENAME TABLE
old_name1 TO new_name1,
old_name2 TO new_name2;
DROP TABLE
Permanently deletes a table and all its data:
-- Dangerous — no undo!
DROP TABLE categories;
-- Safer — won't error if the table doesn't exist
DROP TABLE IF EXISTS categories;
TRUNCATE TABLE
If you want to keep the table structure but delete all rows, use TRUNCATE:
-- Removes all data but keeps the table
TRUNCATE TABLE books;
💡 TRUNCATE vs. DELETE
TRUNCATE TABLE is faster than DELETE FROM table because it doesn't scan rows individually — it drops and recreates the table structure. However, TRUNCATE can't be rolled back in a transaction and resets AUTO_INCREMENT back to 1. Use DELETE when you need fine-grained control; use TRUNCATE when you want to wipe everything quickly.
⚠️ Let's Undo Our Experiments
If you ran any ALTER TABLE or DROP commands on the bookstore tables during this lesson, let's rebuild them cleanly. The easiest way is to drop and recreate:
DROP DATABASE IF EXISTS bookstore;
-- Then re-run the CREATE statements from the
-- "Building Our Practice Database" section above.
We want clean tables for Lesson 5 and beyond.
Inspecting Your Work
After creating or modifying tables, you'll often want to verify the results. Here are the most useful inspection commands:
DESCRIBE — Column Overview
DESCRIBE books;
-- Shorthand:
DESC books;
Shows columns, types, nullability, keys, and defaults in a quick table.
SHOW CREATE TABLE — Full Definition
SHOW CREATE TABLE books\G
This shows the exact SQL that would recreate the table, including all constraints, defaults, character sets, and engine settings. It's the most complete view of a table's definition:
Output (abbreviated):
*************************** 1. row ***************************
Table: books
Create Table: CREATE TABLE `books` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL,
`author` varchar(100) NOT NULL,
`price` decimal(8,2) NOT NULL,
`pages` int DEFAULT NULL,
`published` date DEFAULT NULL,
`in_stock` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
💡 Notice the Differences
MySQL may adjust your definitions slightly: BOOLEAN becomes tinyint(1) (MySQL doesn't have a native boolean type — it uses a tiny integer where 0 = false and 1 = true). DEFAULT TRUE becomes DEFAULT '1'. These are equivalent.
SHOW COLUMNS — Alternative to DESCRIBE
SHOW COLUMNS FROM books;
-- With more detail:
SHOW FULL COLUMNS FROM books;
SHOW FULL COLUMNS adds the collation, privileges, and any column comments.
In phpMyAdmin
Click on a table → Structure tab to see the same information visually. The SQL tab with SHOW CREATE TABLE books; works here too.
Exercises
🏋️ Exercise 1: Build the Bookstore
If you haven't already, create the complete bookstore database from scratch. Write a single .sql file that:
- Creates the
bookstoredatabase (with utf8mb4) - Switches to it with
USE - Creates the
bookstable - Creates the
customerstable - Creates the
categoriestable
Save it as create_bookstore.sql and run it with SOURCE.
✅ Solution
-- create_bookstore.sql
-- Sets up the bookstore database from scratch
CREATE DATABASE IF NOT EXISTS bookstore
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE bookstore;
CREATE TABLE IF NOT EXISTS books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author VARCHAR(100) NOT NULL,
price DECIMAL(8, 2) NOT NULL,
pages INT,
published DATE,
in_stock BOOLEAN DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
city VARCHAR(50),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS categories (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(255)
);
🏋️ Exercise 2: ALTER TABLE Practice
Using ALTER TABLE, make the following changes to the bookstore tables:
- Add a
ratingcolumn tobooks(DECIMAL(3,2), allows NULL — ratings like 4.75) - Add a
phonecolumn tocustomersafteremail - Rename the
descriptioncolumn incategoriestosummary - Verify each change with
DESCRIBE - Undo all changes so the tables match the original definitions
✅ Solution
-- Make changes
ALTER TABLE books ADD COLUMN rating DECIMAL(3,2);
ALTER TABLE customers ADD COLUMN phone VARCHAR(20) AFTER email;
ALTER TABLE categories RENAME COLUMN description TO summary;
-- Verify
DESCRIBE books;
DESCRIBE customers;
DESCRIBE categories;
-- Undo changes
ALTER TABLE books DROP COLUMN rating;
ALTER TABLE customers DROP COLUMN phone;
ALTER TABLE categories RENAME COLUMN summary TO description;
🏋️ Exercise 3: Design Your Own Table
Inside the bookstore database, create a publishers table with:
id— auto-incrementing primary keyname— up to 100 characters, required, uniquecountry— up to 50 charactersfounded_year— integer (e.g., 1925)website— up to 200 characters
After creating it, verify with DESCRIBE and SHOW CREATE TABLE.
✅ Solution
CREATE TABLE IF NOT EXISTS publishers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
country VARCHAR(50),
founded_year INT,
website VARCHAR(200)
);
DESCRIBE publishers;
SHOW CREATE TABLE publishers\G
🎯 Quick Quiz
Question 1: What does IF NOT EXISTS do in a CREATE statement?
Question 2: Which command shows the exact SQL used to create a table?
Question 3: What's the difference between DROP TABLE and TRUNCATE TABLE?
Question 4: What's the recommended naming convention for MySQL tables?
Summary
🎉 Key Takeaways
CREATE DATABASEcreates a new database;USEswitches to itCREATE TABLEdefines a table with columns, data types, and constraints- Always use
IF NOT EXISTS/IF EXISTSfor safe, repeatable scripts - Use
utf8mb4character set for full Unicode support - Follow naming conventions: lowercase, snake_case, plural table names
ALTER TABLElets you add, modify, rename, and drop columns on existing tablesDROP TABLEremoves a table entirely;TRUNCATE TABLEempties data but keeps the structureDESCRIBEgives a quick column overview;SHOW CREATE TABLEshows the full definition- The
bookstoredatabase withbooks,customers, andcategoriestables is our course practice environment
📚 Additional Resources
🚀 What's Next?
You've built the structure — now let's understand the building blocks. In the next lesson, you'll dive deep into data types and constraints — choosing the right type for each column, enforcing rules on your data, and understanding how MySQL stores numbers, text, dates, and more.
🎉 Congratulations!
You've created your first database and tables from scratch. This is the foundation everything else builds on — great work!