MySQLCreating Databases

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

SQL
-- 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

SQL
-- 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;
Note
Always specify CHARACTER SET and COLLATE when creating a database. If you omit them, MySQL uses the server defaults — which may be latin1 on older installations, causing encoding issues later when you store emojis or international characters.
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

SQL
-- 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';
Tip
Use 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

SQL
-- 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                |
+--------------------+
Note
The system databases (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

SQL
-- 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.

SQL
-- 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;
Warning
Converting a large table's character set locks the table and can take minutes or hours. On production databases, use pt-online-schema-change (Percona Toolkit) or gh-ost to perform character set conversions without downtime.
Dropping a Database

SQL
-- 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;
Warning
DROP DATABASE is immediate, permanent, and cannot be undone without a backup. It deletes every table, view, stored procedure, and all data inside the database. Always take a backup first, and double-check you are connected to the correct server.
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

SQL
-- 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;
Tip
Regularly check for tables without primary keys using the last query above. Tables without primary keys cannot use row-based replication correctly, have poor InnoDB performance (no clustered index), and cause problems with logical replication tools like Debezium.
Creating a Database in a Script

Production database setup scripts should be idempotent — safe to run multiple times without error. The standard pattern:

SQL
-- 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;