MySQL 简介
导学
在开始编写任何 SQL 语句之前,你需要知道 MySQL 是什么、它从何而来、以及为什么它成为了全球最流行的开源关系型数据库。本章将回答这三个问题,并通过可运行的 SQL 示例,带你直观感受 MySQL 的核心能力。
定义
MySQL是一个开源的关系型数据库管理系统(Relational Database Management System,简称 RDBMS),由瑞典公司 MySQL AB 开发,现隶属于 Oracle 公司。它使用SQL(Structured Query Language)作为与数据交互的标准语言。
通俗地说:MySQL 就是一个帮你"安全地存数据、快速地取数据"的软件。你可以把它想象成一个超级智能的电子表格管理员,只不过它能处理的行数从几千行到几十亿行都不在话下。
为什么需要 MySQL
在单机时代,数据可以存放在文本文件或 Excel 中。但当应用面临以下场景时,传统方式会彻底失效:
- 并发访问:1000 个用户同时读取或修改同一份数据
- 数据一致性:转账操作中,A 账户扣款和 B 账户收款必须同时成功或同时失败
- 海量数据:亿级记录的快速检索
- 安全隔离:不同用户只能看到自己有权限的数据
上图展示了 MySQL 的核心定位:作为应用程序与持久化数据之间的"中间层",统一管理并发、安全和一致性。
MySQL 5.7 的核心特性
MySQL 5.7 是 MySQL 发展史上的一个里程碑版本(发布于 2015 年),在 5.6 的基础上进行了大量增强:
| 特性 | 说明 |
|---|---|
| 原生 JSON 支持 | 引入 JSON 数据类型及配套函数,可存储和查询半结构化数据 |
| GIS 空间数据增强 | 支持 InnoDB 存储空间索引,地理信息查询性能大幅提升 |
| 并行复制 | 从库应用 Binlog 时可并行执行,显著降低主从延迟 |
| 多源复制 | 一个从库可同时从多个主库同步数据 |
| InnoDB 性能优化 | 更快的在线 DDL、临时表优化、自适应哈希索引增强 |
| 安全增强 | 默认启用 SSL、密码过期策略、安装时自动生成 root 密码 |
特性演示:原生 JSON 支持
下面通过一个完整的示例,演示 MySQL 5.7 的 JSON 数据类型。
当前数据状态:我们需要创建一张员工表,其中员工技能属性用 JSON 存储,因为不同员工的技能信息可能不同。
-- 1. 创建测试数据库
CREATE DATABASE IF NOT EXISTS demo_db
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE demo_db;
-- 2. 创建包含 JSON 列的员工表
CREATE TABLE employees (
emp_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
emp_name VARCHAR(20) NOT NULL COMMENT '员工姓名',
dept VARCHAR(20) COMMENT '部门',
attrs JSON COMMENT '技能属性(JSON格式)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
操作语句:插入几条带有不同 JSON 属性的员工记录。
INSERT INTO employees (emp_name, dept, attrs) VALUES
('大翔', '技术部', '{"skill": "MySQL", "level": 5}'),
('白歌', '技术部', '{"skill": "Python", "level": 4}');
操作后的数据状态:
SELECT * FROM employees;
| emp_id | emp_name | dept | attrs |
|---|---|---|---|
| 1 | 大翔 | 技术部 | {"skill": "MySQL", "level": 5} |
| 2 | 白歌 | 技术部 | {"skill": "Python", "level": 4} |
结果解读:JSON 列可以存储结构不固定的半结构化数据,同一列中不同行可以有不同的字段。这是 MySQL 5.7 之前无法做到的。
继续演示如何从 JSON 中提取字段:
-- 提取所有员工的 skill 属性
SELECT
emp_name,
JSON_UNQUOTE(JSON_EXTRACT(attrs, '$.skill')) AS skill,
JSON_EXTRACT(attrs, '$.level') AS level
FROM employees;
| emp_name | skill | level |
|---|---|---|
| 大翔 | MySQL | 5 |
| 白歌 | Python | 4 |
结果解读:JSON_EXTRACT 使用 JSON Path 语法($.key)提取 JSON 对象中的字段。对于不存在的路径,返回 NULL 而不是报错。JSON_UNQUOTE 用于去除结果外层的双引号。
清理测试数据:
DROP DATABASE IF EXISTS demo_db;
存储引擎:MySQL 的"可换心脏"
MySQL 与其他数据库最大的区别之一,是它支持可插拔的存储引擎(Storage Engine)。存储引擎决定了数据如何存储、如何索引、如何加锁。
MySQL 5.7 中,InnoDB是默认且推荐使用的存储引擎。除非你有特殊需求(如数据仓库场景下的只读批量加载),否则无需考虑其他引擎。
存储引擎对比演示
下面通过创建两张结构相同但引擎不同的表,直观展示存储引擎的差异。
当前数据状态:
-- 创建测试数据库
CREATE DATABASE IF NOT EXISTS engine_demo
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE engine_demo;
操作语句:
-- 创建 InnoDB 表
CREATE TABLE employees_innodb (
emp_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
emp_name VARCHAR(20) NOT NULL,
score DECIMAL(5,2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 创建 MyISAM 表
CREATE TABLE employees_myisam (
emp_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
emp_name VARCHAR(20) NOT NULL,
score DECIMAL(5,2)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
操作后的数据状态:
-- 查看两张表的引擎信息
SELECT
table_name,
engine
FROM information_schema.tables
WHERE table_schema = 'engine_demo'
AND table_name IN ('employees_innodb', 'employees_myisam');
| table_name | engine |
|---|---|
| employees_innodb | InnoDB |
| employees_myisam | MyISAM |
结果解读:同一个数据库中可以存在不同引擎的表。information_schema.tables 是查询表元数据的标准方式。
继续演示事务支持差异(这是 InnoDB 和 MyISAM 最核心的区别):
-- 向两张表插入相同的数据
INSERT INTO employees_innodb (emp_name, score) VALUES ('大翔', 100);
INSERT INTO employees_myisam (emp_name, score) VALUES ('大翔', 100);
-- 查看插入前的状态
SELECT * FROM employees_innodb;
| emp_id | emp_name | score |
|---|---|---|
| 1 | 大翔 | 100 |
SELECT * FROM employees_myisam;
| emp_id | emp_name | score |
|---|---|---|
| 1 | 大翔 | 100 |
操作语句:尝试在 InnoDB 表中使用事务回滚。
-- InnoDB:开启事务,插入数据,然后回滚
START TRANSACTION;
INSERT INTO employees_innodb (emp_name, score) VALUES ('白歌', NULL);
ROLLBACK;
-- 查看回滚后的状态
SELECT * FROM employees_innodb;
| emp_id | emp_name | score |
|---|---|---|
| 1 | 大翔 | 100 |
操作语句:在 MyISAM 表中尝试相同操作。
-- MyISAM:尝试开启事务并回滚(MyISAM 不支持事务)
START TRANSACTION;
INSERT INTO employees_myisam (emp_name, score) VALUES ('白歌', NULL);
ROLLBACK;
-- 查看 MyISAM 表的状态
SELECT * FROM employees_myisam;
| emp_id | emp_name | score |
|---|---|---|
| 1 | 大翔 | 100 |
| 2 | 白歌 | NULL |
结果解读:InnoDB 支持事务,ROLLBACK 成功撤销了未提交的插入,表中仍只有大翔。MyISAM 不支持事务,虽然执行了 ROLLBACK,但白歌已经被永久写入,无法回滚。这就是为什么生产环境必须使用 InnoDB。
清理测试数据:
DROP DATABASE IF EXISTS engine_demo;
面试考点
Q:MySQL 5.7 相比于 5.6 最大的改进是什么?
原生 JSON 支持和并行复制。JSON 类型让 MySQL 可以更好地应对半结构化数据场景;并行复制则解决了主从架构下从库延迟(Slave Lag)的痛点。
Q:MySQL 和 PostgreSQL 的核心区别是什么?
MySQL 以"简单、快速、易部署"著称,存储引擎可插拔,社区生态极大;PostgreSQL 以"标准兼容、功能丰富"著称,支持更复杂的查询和高级数据类型。选择取决于场景:Web 应用高并发读写选 MySQL,复杂分析查询选 PostgreSQL。
Q:为什么不推荐使用 MyISAM 引擎?
MyISAM 不支持事务、不支持行级锁、不支持崩溃恢复。一旦表损坏,修复过程漫长且可能丢失数据。MySQL 8.0 已彻底移除 MyISAM 的系统表依赖。
小结
MySQL 是一个开源关系型数据库管理系统,MySQL 5.7 在其发展史上是功能与稳定性平衡极佳的版本。理解它的核心定位(应用与数据之间的中间层)和存储引擎架构,是后续学习所有 SQL 语句的前提。
下一章引子:知道了 MySQL 是什么,接下来我们需要学会如何与它"对话"——连接到服务器,并执行第一条 SQL 查询。