Creating Databases in MySQL
A database (or schema — the terms are interchangeable in MySQL) is the top-level container for your tables, views, stored procedures, and functions. Before you can create tables or store data, you need a database to put them in.
This tutorial covers the full lifecycle: creating databases with proper character sets, viewing existing databases, switching between them, and dropping databases safely.
CREATE DATABASE Syntax
-- Minimal syntax
CREATE DATABASE myapp;
-- Full syntax
CREATE DATABASE [IF NOT EXISTS] database_name
[CHARACTER SET charset_name]
[COLLATE collation_name]
[ENCRYPTION {'Y'|'N'}]
[COMMENT 'text'];Basic Examples
-- Create a simple database CREATE DATABASE blog; -- Create only if it doesn't already exist (no error if it does) CREATE DATABASE IF NOT EXISTS blog; -- Create with explicit character set and collation (recommended) CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Equivalent using SCHEMA (synonym for DATABASE in MySQL) CREATE SCHEMA IF NOT EXISTS myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Character Set and Collation
The character set defines which characters can be stored. The collation defines how those characters are compared and sorted.
Charset | Description | Max bytes/char | Use when |
|---|---|---|---|
utf8mb4 | Full Unicode including emoji | 4 | New databases — this should be your default |
utf8 (utf8mb3) | Unicode, no emoji (BMP only) | 3 | Legacy — avoid for new projects |
latin1 | Western European | 1 | Legacy systems only |
ascii | US ASCII only | 1 | Only for ASCII-only data (rare) |
Collation | Case Sensitive? | Accent Sensitive? | Use when |
|---|---|---|---|
utf8mb4_unicode_ci | No (ci) | No | General purpose — case-insensitive comparisons |
utf8mb4_0900_ai_ci | No (ci) | No (ai) | MySQL 8.0 default — Unicode 9.0, faster |
utf8mb4_bin | Yes | Yes | Binary comparison — passwords, tokens, hex values |
utf8mb4_general_ci | No (ci) | No | Old default — less correct than unicode_ci |
-- Show all available character sets SHOW CHARACTER SET; -- Show collations for utf8mb4 SHOW COLLATION WHERE Charset = 'utf8mb4'; -- See the server's default character set and collation SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server';
utf8mb4_unicode_ci for most databases. Use utf8mb4_bin for columns storing passwords, tokens, or case-sensitive identifiers. Using utf8mb4_0900_ai_ci (MySQL 8.0 default) is also a good modern choice.Viewing and Using Databases
-- List all databases you have access to SHOW DATABASES; -- List databases matching a pattern SHOW DATABASES LIKE 'myapp%'; -- Select a database to work with USE myapp; -- Check which database is currently selected SELECT DATABASE();
+--------------------+ | Database | +--------------------+ | information_schema | | myapp | | mysql | | performance_schema | | sys | +--------------------+
information_schema, mysql, performance_schema, sys) are always present. Never drop or directly modify the mysql database — it stores user accounts, privileges, and server configuration.Viewing Database Details
-- Show the CREATE DATABASE statement for an existing database SHOW CREATE DATABASE myapp; -- Get detailed info from information_schema SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'myapp';
+---------+----------------------------+------------------------+ | SCHEMA | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | +---------+----------------------------+------------------------+ | myapp | utf8mb4 | utf8mb4_unicode_ci | +---------+----------------------------+------------------------+
Altering a Database
You can change a database's character set or collation after creation. Note this only changes the default for new tables — existing tables are not automatically converted.
-- Change the default character set and collation ALTER DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- To convert existing tables, you must alter each table individually: ALTER TABLE my_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Dropping a Database
-- Drop a database and all its contents permanently DROP DATABASE myapp; -- Drop only if it exists (no error if it doesn't) DROP DATABASE IF EXISTS myapp; -- SCHEMA is synonymous with DATABASE DROP SCHEMA IF EXISTS myapp;
Database vs Schema in MySQL
In MySQL, the terms DATABASE and SCHEMA are completely synonymous — they refer to
the same object. CREATE DATABASE and CREATE SCHEMA do identical things.
SHOW DATABASES and information_schema's SCHEMATA table list the same objects.
This differs from other database systems:
System | Hierarchy |
|---|---|
MySQL | Server → Database (= Schema) → Table |
PostgreSQL | Server → Database → Schema → Table (three levels!) |
SQL Server | Server → Database → Schema → Table (three levels!) |
Oracle | Server → Schema (= User) → Table |
In PostgreSQL and SQL Server, a schema is a namespace within a database — you can have
multiple schemas in one database (e.g., public.users and hr.employees).
MySQL has only one level, so "database" and "schema" mean the same thing.
Database Naming Conventions
Use lowercase letters, numbers, and underscores only — avoid uppercase, hyphens, or spaces which require quoting in SQL.
Be descriptive: <code>ecommerce_db</code>, <code>analytics_warehouse</code>, <code>auth_service</code>
Use a suffix or prefix to distinguish environments: <code>myapp_dev</code>, <code>myapp_staging</code>, <code>myapp_prod</code>
Keep names reasonably short — MySQL has a 64-character limit for database names, but shorter is easier to type.
Avoid MySQL reserved words as database names: information_schema, mysql, performance_schema, sys, test
The information_schema Database
information_schema is a virtual read-only database that provides metadata about
every object on the MySQL server. You can query it like any other database, but it reflects
live server state — you cannot INSERT, UPDATE, or DELETE from it.
Key tables in information_schema:
Table | Contains |
|---|---|
SCHEMATA | All databases and their character sets |
TABLES | All tables with row counts, sizes, engine, and more |
COLUMNS | All columns with types, defaults, and constraints |
KEY_COLUMN_USAGE | Foreign key relationships and primary key info |
STATISTICS | All indexes with columns and selectivity |
VIEWS | All views with their defining SQL |
ROUTINES | Stored procedures and functions |
TRIGGERS | All triggers with timing and event |
USER_PRIVILEGES | Global privileges for each user |
-- Find all databases using utf8mb4
SELECT SCHEMA_NAME
FROM information_schema.SCHEMATA
WHERE DEFAULT_CHARACTER_SET_NAME = 'utf8mb4';
-- Find all tables larger than 100MB
SELECT TABLE_SCHEMA, TABLE_NAME,
ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 0) AS size_mb
FROM information_schema.TABLES
WHERE (DATA_LENGTH + INDEX_LENGTH) > 100 * 1024 * 1024
ORDER BY size_mb DESC;
-- Find all tables that do NOT have a PRIMARY KEY
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES t
WHERE TABLE_TYPE = 'BASE TABLE'
AND NOT EXISTS (
SELECT 1
FROM information_schema.KEY_COLUMN_USAGE k
WHERE k.TABLE_SCHEMA = t.TABLE_SCHEMA
AND k.TABLE_NAME = t.TABLE_NAME
AND k.CONSTRAINT_NAME = 'PRIMARY'
)
ORDER BY TABLE_SCHEMA, TABLE_NAME;Creating a Database in a Script
Production database setup scripts should be idempotent — safe to run multiple times without error. The standard pattern:
-- setup.sql — idempotent database creation script -- Create the database if it doesn't exist CREATE DATABASE IF NOT EXISTS myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Select it USE myapp; -- Create application user with minimal privileges CREATE USER IF NOT EXISTS 'appuser'@'localhost' IDENTIFIED BY 'your_secure_password_here'; GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'localhost'; -- Create admin user for migrations CREATE USER IF NOT EXISTS 'app_migration'@'localhost' IDENTIFIED BY 'migration_password_here'; GRANT ALL PRIVILEGES ON myapp.* TO 'app_migration'@'localhost'; FLUSH PRIVILEGES; SELECT 'Database setup complete.' AS status;