Skip to content

这是我学习 MySQL 时整理的入门笔记。之前写事务文章时发现绕不开数据库原理(undo log、索引),索性把 MySQL 系统梳理一遍。这篇先解决"会用",核心原理(事务/索引)后面单独成篇。

一、MySQL 是什么

MySQL 是关系型数据库(RDBMS)——数据存在"表"里,表由行和列组成,表和表之间通过主外键关联。与之相对的是 MongoDB(文档型,存 JSON 文档)。

对比MySQL(关系型)MongoDB(文档型)
数据模型表/行/列(结构化,Schema 固定)文档(JSON 类,Schema 灵活)
查询语言SQL(结构化查询)方法链 / 类 JSON 查询
事务强 ACID也支持(文档级事务)
适用强一致、复杂关联、金融订单灵活结构、快速迭代、日志

选择:业务数据(订单/用户/库存)用 MySQL;结构多变/快速迭代(CMS、日志)可考虑 MongoDB。

二、Docker 安装 + 连接

本地开发用 Docker 一条命令:

bash
docker run -d --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0

连接(命令行):

bash
docker exec -it mysql mysql -uroot -p123456

MySQL 8.0 注意:认证插件是 caching_sha2_password,老客户端(如某些 Java 驱动旧版本)连不上,需要 ALTER USER ... IDENTIFIED WITH mysql_native_password BY '...'

三、核心概念(先记住这几个)

概念说明
数据库(database)一堆表的集合,一个实例可建多个库
表(table)数据存储单元,行列结构
主键(primary key)每行唯一标识,自动建索引
索引(index)加速查询的数据结构(B+Tree)
事务(transaction)一组要么全成功要么全回滚的操作

四、CRUD 实战

sql
-- 建库建表
CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARSET utf8mb4;
USE shop;

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    balance DECIMAL(10,2) DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- 增
INSERT INTO user(name, balance) VALUES ('BinMaker', 100.00);

-- 查
SELECT * FROM user WHERE balance > 50 ORDER BY balance DESC LIMIT 10;

-- 改
UPDATE user SET balance = balance - 10 WHERE id = 1;

-- 删
DELETE FROM user WHERE id = 2;

注意ENGINE=InnoDB 是默认的,显式写出来是为了强调——InnoDB 才有事务和行级锁(MyISAM 没有,见下)。

五、事务:ACID + 回滚原理

MySQL 的 InnoDB 引擎支持事务,ACID 四特性:

特性含义实现
A 原子性要么全成功要么全回滚undo log(记录旧值,回滚时恢复)
C 一致性事务前后数据完整应用层约束 + 数据库约束
I 隔离性事务间互不干扰锁 + MVCC
D 持久性提交后不丢redo log(崩溃恢复)

为什么能回滚(细节见我的《@Transactional 详解》):InnoDB 在每次修改前把旧值写进 undo logROLLBACK 时按日志把数据恢复成修改前——这就是"回滚"的本质,不是恢复整个数据库。

sql
START TRANSACTION;
UPDATE user SET balance = balance - 100 WHERE id = 1;
-- 发现余额不够,回滚
ROLLBACK;
-- 数据没变

六、索引:为什么查询快

索引的本质是B+Tree 数据结构——类似字典的目录,把"找数据"从全表扫描(O(n))变成树查找(O(log n))。

sql
-- 建索引
CREATE INDEX idx_balance ON user(balance);
-- 走索引查询(EXPLAIN 看 key 字段)
EXPLAIN SELECT * FROM user WHERE balance > 50;

一条 SQL 的执行流程(连接器→分析器→优化器→执行器→存储引擎):

一条 SQL 查询的执行流程

索引核心要点

  • 主键自动建索引;WHERE/JOIN/ORDER BY 的字段适合建索引
  • 最左前缀:联合索引 (a, b, c)aa,b 走索引,查 b 不走
  • 索引不是越多越好(写入变慢、占空间)
  • EXPLAINtype(all=全表扫,range/ref/const 更好)和 rows(扫描行数)

七、和 Spring Boot 集成

xml
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>
yaml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/shop?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: "123456"

配合 MyBatis-Plus / Spring Data JPA 使用(ORM 见《MyBatis 快速入门》),事务用 @Transactional(见《Spring @Transactional 详解》),高并发缓存加速用 Redis(见《Redis 快速入门》)。

小结

  • MySQL = 关系型数据库(表/行/列 + SQL),MongoDB = 文档型(灵活 Schema)
  • InnoDB 引擎提供**事务(undo log 回滚)**和行级锁——默认引擎
  • 索引 = B+Tree,加速查询,EXPLAIN 分析是否走索引
  • 一条 SQL:连接器 → 分析器 → 优化器 → 执行器 → 存储引擎

下一步可以看我的《@Transactional 详解》(事务回滚原理)、《RabbitMQ 快速入门》(中间件);事务并发控制见《MySQL 事务与隔离级别》,查询优化见《MySQL 索引详解》,之后写《分库分表》专题。