创建数据库
导学
连接服务器后,第一步就是创建一个属于自己的数据库。本节学习 CREATE DATABASE 语句的语法、字符集设置原则,以及创建后的验证方法。每个知识点都会通过完整的 SQL 示例和前后数据对比来呈现。
定义
CREATE DATABASE:SQL 中的数据定义语言(DDL)语句,用于在 MySQL 服务器中创建一个新的数据库容器。创建后,该数据库内可以建表、建视图、建索引等。
基本语法
CREATE DATABASE [IF NOT EXISTS] 数据库名
[DEFAULT CHARACTER SET 字符集]
[DEFAULT COLLATE 排序规则];
IF NOT EXISTS:可选,如果数据库已存在则不报错(避免重复执行时出错)CHARACTER SET:指定字符集,如utf8mb4COLLATE:指定排序规则,如utf8mb4_unicode_ci
完整示例:创建数据库
场景一:查看创建前的服务器状态
当前数据状态:先查看服务器上已有的数据库。
SHOW DATABASES;
典型的执行结果:
| Database |
|---|
| information_schema |
| mysql |
| performance_schema |
| sys |
结果解读:新安装的 MySQL 5.7 默认有 4 个系统数据库。其中 information_schema、performance_schema、sys、mysql 存放元数据、性能统计和系统配置,不要轻易修改它们。
场景二:创建最简单的数据库(不推荐)
操作语句:
CREATE DATABASE test_db;
操作后的数据状态:
SHOW DATABASES;
| Database |
|---|
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db |
结果解读:虽然语法正确且数据库已创建,但不指定字符集是危险的做法。MySQL 5.7 默认字符集是 latin1,不支持中文存储,后续插入中文会产生乱码。
验证默认字符集:
SHOW CREATE DATABASE test_db;
| Database | Create Database |
|---|---|
| test_db | CREATE DATABASE test_db /*!40100 DEFAULT CHARACTER SET latin1 */ |
结果解读:可以看到默认字符集是 latin1,这意味着如果不做任何修改,在该库中创建表并插入中文时会出现乱码。
场景三:创建支持中文的数据库(推荐写法)
当前数据状态:test_db 已存在,现在创建一个规范的数据库。
-- 先删除不规范的测试库
DROP DATABASE IF EXISTS test_db;
操作语句:
CREATE DATABASE IF NOT EXISTS library
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
操作后的数据状态:
SHOW DATABASES;
| Database |
|---|
| information_schema |
| library |
| mysql |
| performance_schema |
| sys |
验证字符集设置:
SHOW CREATE DATABASE library;
| Database | Create Database |
|---|---|
| library | CREATE DATABASE library /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */ |
结果解读:
utf8mb4是 MySQL 5.7 推荐的字符集,它是 UTF-8 的完整实现,支持存储 emoji 和生僻汉字utf8mb4_unicode_ci是通用的排序规则,对多语言排序更合理IF NOT EXISTS让这条语句可以安全地重复执行(例如在初始化脚本中)
场景四:验证字符集差异的实际影响
当前数据状态:test_db(latin1)已被删除,现在重新创建它来对比中文存储效果。
-- 创建 latin1 字符集的数据库(模拟旧系统)
CREATE DATABASE IF NOT EXISTS legacy_db
DEFAULT CHARACTER SET latin1;
-- 在 legacy_db 中创建表并插入中文
USE legacy_db;
CREATE TABLE messages (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(100)
) ENGINE=InnoDB;
操作语句:尝试插入中文数据。
INSERT INTO messages (content) VALUES ('你好,MySQL!');
操作后的数据状态:
SELECT * FROM messages;
| id | content |
|---|---|
| 1 | ????MySQL! |
结果解读:latin1 字符集无法正确存储中文,插入的中文变成了问号乱码。这就是为什么不指定 utf8mb4 是危险的。
现在对比 utf8mb4 的效果:
USE library;
CREATE TABLE messages (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO messages (content) VALUES ('你好,MySQL!');
SELECT * FROM messages;
| id | content |
|---|---|
| 1 | 你好,MySQL! |
结果解读:在 utf8mb4 环境下,中文被正确存储和显示。所有新数据库都应显式指定 utf8mb4。
清理测试数据:
DROP DATABASE IF EXISTS legacy_db;
DROP TABLE IF EXISTS library.messages;
为什么必须用 utf8mb4 而非 utf8?
MySQL 早期的 utf8 实现是"阉割版"的 UTF-8,每个字符最多只用 3 字节,无法存储 4 字节的字符(如 emoji 😀、某些中文生僻字)。utf8mb4 才是标准的 UTF-8 实现。
场景五:utf8 与 utf8mb4 的实际对比
当前数据状态:
-- 创建 utf8 数据库(注意不是 utf8mb4)
CREATE DATABASE IF NOT EXISTS utf8_demo
DEFAULT CHARACTER SET utf8;
USE utf8_demo;
CREATE TABLE emoji_test (
id INT PRIMARY KEY AUTO_INCREMENT,
note VARCHAR(50)
) ENGINE=InnoDB;
操作语句:尝试插入 emoji。
INSERT INTO emoji_test (note) VALUES ('Hello 😀');
操作后的数据状态:这条语句会报错:
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'note'
结果解读:utf8 无法存储 4 字节的 emoji 字符,直接报错。现在换到 utf8mb4:
USE library;
CREATE TABLE emoji_test (
id INT PRIMARY KEY AUTO_INCREMENT,
note VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO emoji_test (note) VALUES ('Hello 😀');
SELECT * FROM emoji_test;
| id | note |
|---|---|
| 1 | Hello 😀 |
结果解读:utf8mb4 成功存储了 emoji。任何现代应用都应使用 utf8mb4。
清理测试数据:
DROP DATABASE IF EXISTS utf8_demo;
DROP TABLE IF EXISTS library.emoji_test;
💡 面试必考点:
utf8在 MySQL 中不是真正的 UTF-8,utf8mb4才是。
修改已有数据库的字符集
场景六:ALTER DATABASE 修改字符集
当前数据状态:
-- 先创建一个 latin1 数据库(模拟需要整改的旧库)
CREATE DATABASE IF NOT EXISTS old_project
DEFAULT CHARACTER SET latin1;
SHOW CREATE DATABASE old_project;
| Database | Create Database |
|---|---|
| old_project | CREATE DATABASE old_project /*!40100 DEFAULT CHARACTER SET latin1 */ |
操作语句:
ALTER DATABASE old_project
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
操作后的数据状态:
SHOW CREATE DATABASE old_project;
| Database | Create Database |
|---|---|
| old_project | CREATE DATABASE old_project /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */ |
结果解读:ALTER DATABASE 只修改数据库的默认字符集设置,不会影响已存在的表。已存在的表需要单独用 ALTER TABLE 修改。
验证这一点:
USE old_project;
-- 在修改字符集之前创建的表
CREATE TABLE old_table (
name VARCHAR(50)
) ENGINE=InnoDB;
-- 查看表的字符集
SHOW CREATE TABLE old_table;
输出中仍能看到 DEFAULT CHARSET=latin1,证明 ALTER DATABASE 不修改已有表。
清理测试数据:
DROP DATABASE IF EXISTS old_project;
删除数据库(危险操作)
场景七:安全删除数据库
当前数据状态:
SHOW DATABASES;
| Database |
|---|
| information_schema |
| library |
| mysql |
| performance_schema |
| sys |
操作语句:
DROP DATABASE IF EXISTS library;
操作后的数据状态:
SHOW DATABASES;
| Database |
|---|
| information_schema |
| mysql |
| performance_schema |
| sys |
结果解读:library 数据库已被彻底删除,包括其中的所有表、数据、视图、存储过程等。此操作不可逆,执行前务必确认。IF EXISTS 可以避免数据库不存在时报错。
⚠️ 警告:
DROP DATABASE会删除数据库及其内部的所有表、数据、视图。此操作不可逆,执行前务必确认。
常见误区
| 误区 | 正解 |
|---|---|
| "utf8 够用了,utf8mb4 没必要" | utf8 无法存储 emoji 和补充汉字,任何现代应用都应使用 utf8mb4。 |
| "字符集在表层面设置就够了" | 数据库层面的默认字符集会影响所有新建表。在库层面设置好,可以减少后续遗漏。 |
CREATE SCHEMA 和 CREATE DATABASE 不同 | 在 MySQL 中,SCHEMA 是 DATABASE 的同义词,两者完全等价。 |
验证 CREATE SCHEMA 的等价性:
CREATE SCHEMA IF NOT EXISTS schema_demo
DEFAULT CHARACTER SET utf8mb4;
SHOW DATABASES LIKE 'schema_demo';
| Database (schema_demo) |
|---|
| schema_demo |
DROP SCHEMA IF EXISTS schema_demo;
结果解读:CREATE SCHEMA 和 CREATE DATABASE 在 MySQL 中完全等价,都会创建数据库。DROP SCHEMA 也等价于 DROP DATABASE。
面试考点
Q:utf8mb4 和 utf8 的区别是什么?
utf8在 MySQL 中最大只支持 3 字节,属于"阉割版 UTF-8";utf8mb4支持 4 字节,是真正的 UTF-8,可存储 emoji 和所有 Unicode 字符。MySQL 8.0 已将默认字符集改为utf8mb4。
Q:utf8mb4_general_ci 和 utf8mb4_unicode_ci 怎么选?
general_ci排序速度略快,但对某些语言的排序规则不够精确;unicode_ci遵循 Unicode 排序标准,更精确,对中文排序也更合理。推荐unicode_ci,除非有极致性能需求。
Q:如何修改已有数据库的字符集?
使用
ALTER DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。但注意:这只影响新创建的表,已存在的表需要单独用ALTER TABLE修改。
小结
- 创建数据库的核心语句是
CREATE DATABASE - 必须显式指定
CHARACTER SET utf8mb4 utf8mb4才是真正的 UTF-8,utf8是历史遗留的缺陷实现IF NOT EXISTS和IF EXISTS是编写可重复执行脚本的好习惯ALTER DATABASE只改默认值,不影响已有表
下一章引子:数据库创建好了,接下来要在里面创建数据表。