{T}

数据库核心概念详解

一、学习资源推荐

1.1 在线学习平台

1. 慕课网

  • 网址:https://www.imooc.com/
  • 搜索关键词:数据库、MySQL、SQL
  • 特点:免费和付费课程丰富

2. 菜鸟教程

3. MySQL 官方教程

1.2 学习重点

code
SQL 学习重点:
│
├── 数据查询(SELECT)
│   ├── 基础查询
│   ├── 条件查询(WHERE)
│   ├── 排序(ORDER BY)
│   ├── 分组(GROUP BY)
│   └── 关联查询(JOIN)
│
├── 数据操作(DML)
│   ├── 插入(INSERT)
│   ├── 更新(UPDATE)
│   └── 删除(DELETE)
│
└── 数据定义(DDL)
    ├── 创建表(CREATE TABLE)
    ├── 修改表(ALTER TABLE)
    └── 删除表(DROP TABLE)

二、表(Table)的概念

2.1 什么是表?

定义:数据库中存储数据的结构,类似于电子表格(Excel)

类比理解

  • 数据库表 ≈ Excel 工作表
  • 表头 ≈ 列名(字段名)
  • 一行数据 ≈ 一条记录

示例:用户表

code
┌────┬──────────┬────────┬────────┐
│ ID │ username │  name  │ gender │
├────┼──────────┼────────┼────────┤
│  1 │ zhangsan │  张三  │   1    │
│  2 │ lisi     │  李四  │   2    │
│  3 │ wangwu   │  王五  │   1    │
└────┴──────────┴────────┴────────┘

表头(列名):ID、username、name、gender
记录(行):3 条记录

2.2 表的组成要素

code
表的组成要素:
│
├── 表名(Table Name)
│   └── 标识表的名称,如:users、orders
│
├── 列/字段(Column/Field)
│   └── 表头,定义数据的类型和含义
│
├── 行/记录(Row/Record)
│   └── 一条完整的数据
│
└── 单元格(Cell)
    └── 具体的数据值

2.3 创建表的 SQL 语句

sql
-- 创建用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  name VARCHAR(50),
  gender TINYINT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 查看表结构
DESC users;

-- 查看建表语句
SHOW CREATE TABLE users;

-- 删除表
DROP TABLE users;

三、列(Column/Field)的概念

3.1 什么是列?

定义:一组相同类型的数据,代表一个特定的含义

特点

  • 数据类型相同
  • 含义特定
  • 可设置约束条件

示例

sql
-- username 列
数据类型:VARCHAR(50)
含义:用户名
约束:NOT NULL(不能为空)

-- gender 列
数据类型:TINYINT
含义:性别(1-男,2-女)
约束:DEFAULT 0(默认为 0)

3.2 常见数据类型

数值类型

类型大小范围说明
TINYINT1 字节-128 ~ 127小整数,状态值
INT4 字节-21亿 ~ 21亿整数,ID
BIGINT8 字节非常大大整数,时间戳
DECIMAL可变精确小数金额
FLOAT4 字节近似小数评分

字符串类型

类型说明示例
CHAR(n)固定长度手机号:CHAR(11)
VARCHAR(n)可变长度用户名:VARCHAR(50)
TEXT长文本文章内容

日期时间类型

类型格式说明
DATEYYYY-MM-DD日期
TIMEHH:MM:SS时间
DATETIMEYYYY-MM-DD HH:MM:SS日期时间
TIMESTAMP时间戳自动更新

完整建表示例

sql
CREATE TABLE products (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT '商品ID',
  name VARCHAR(100) NOT NULL COMMENT '商品名称',
  price DECIMAL(10, 2) NOT NULL COMMENT '价格',
  stock INT DEFAULT 0 COMMENT '库存',
  status TINYINT DEFAULT 1 COMMENT '状态:1-上架,0-下架',
  description TEXT COMMENT '商品描述',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';

3.3 列的约束条件

sql
CREATE TABLE users (
  -- PRIMARY KEY:主键约束
  id INT PRIMARY KEY AUTO_INCREMENT,
  
  -- NOT NULL:非空约束
  username VARCHAR(50) NOT NULL,
  
  -- UNIQUE:唯一约束
  email VARCHAR(100) UNIQUE,
  
  -- DEFAULT:默认值
  status TINYINT DEFAULT 1,
  
  -- CHECK:检查约束
  age INT CHECK (age >= 0 AND age <= 150),
  
  -- FOREIGN KEY:外键约束
  dept_id INT,
  FOREIGN KEY (dept_id) REFERENCES departments(id)
);

四、记录(Record/Row)的概念

4.1 什么是记录?

定义:一行完整的、相关的数据

特点

  • 包含所有列的值
  • 代表一个完整的实体
  • 通过主键唯一标识

示例

sql
-- 一条记录
{
  id: 1,
  username: 'zhangsan',
  name: '张三',
  gender: 1,
  created_at: '2024-01-01 10:00:00'
}

4.2 记录的操作

1. 插入记录(INSERT)

sql
-- 插入单条记录
INSERT INTO users (username, name, gender)
VALUES ('zhangsan', '张三', 1);

-- 插入多条记录
INSERT INTO users (username, name, gender) VALUES
  ('lisi', '李四', 2),
  ('wangwu', '王五', 1);

2. 查询记录(SELECT)

sql
-- 查询所有记录
SELECT * FROM users;

-- 查询特定字段
SELECT id, username, name FROM users;

-- 条件查询
SELECT * FROM users WHERE gender = 1;

-- 排序
SELECT * FROM users ORDER BY created_at DESC;

-- 分页
SELECT * FROM users LIMIT 0, 10;  -- 第 1 页,每页 10 条
SELECT * FROM users LIMIT 10, 10;  -- 第 2 页,每页 10 条

3. 更新记录(UPDATE)

sql
-- 更新单个字段
UPDATE users SET name = '张三丰' WHERE id = 1;

-- 更新多个字段
UPDATE users 
SET name = '张三丰', gender = 1 
WHERE id = 1;

4. 删除记录(DELETE)

sql
-- 删除特定记录
DELETE FROM users WHERE id = 1;

-- 条件删除
DELETE FROM users WHERE status = 0;

五、主键(Primary Key)的概念

5.1 什么是主键?

定义:表中唯一标识每一行记录的字段或字段组合

核心特点

  • 唯一性:每条记录的主键值唯一
  • 非空性:主键值不能为 NULL
  • 稳定性:主键值不应频繁变化
  • 自带索引:主键自动创建索引

类比理解

  • 主键 ≈ 身份证号(唯一标识一个人)
  • 主键 ≈ 学号(唯一标识一个学生)

5.2 主键的类型

1. 单列主键

sql
-- 单列主键
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  name VARCHAR(50)
);

-- 或者在表定义后指定
CREATE TABLE users (
  id INT AUTO_INCREMENT,
  username VARCHAR(50),
  name VARCHAR(50),
  PRIMARY KEY (id)
);

2. 联合主键(复合主键)

sql
-- 联合主键:多个字段组合作为主键
CREATE TABLE student_courses (
  student_id INT,
  course_id INT,
  score DECIMAL(5, 2),
  PRIMARY KEY (student_id, course_id)  -- 联合主键
);

联合主键特点

  • 单个字段可以重复
  • 字段组合必须唯一
  • 适用于多对多关系的中间表

5.3 主键的作用

code
主键的三大作用:
│
├── 1⃣ 唯一标识
│   └── 通过主键值唯一确定一条记录
│
├── 2⃣ 建立索引
│   └── 主键自动创建索引,提高查询速度
│
└── 3⃣ 关联关系
    └── 主键作为外键,建立表之间的关联

5.4 主键 vs 唯一键(UNIQUE)

对比项主键(PRIMARY KEY)唯一键(UNIQUE)
唯一性必须必须
非空性必须允许 NULL
数量每表只能有一个可以有多个
索引自动创建聚簇索引自动创建非聚簇索引
用途标识记录防止重复
sql
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,  -- 主键
  username VARCHAR(50) UNIQUE,         -- 唯一键
  email VARCHAR(100) UNIQUE,           -- 唯一键
  phone VARCHAR(20)                    -- 普通字段
);

5.5 主键的最佳实践

code
主键设计原则:
│
├──  推荐做法
│   ├── 使用自增整数(AUTO_INCREMENT)
│   ├── 主键值简短、稳定
│   ├── 不要使用业务字段作为主键
│   └── 不要修改主键值
│
└──  不推荐做法
    ├── 使用 UUID(太长、索引效率低)
    ├── 使用业务字段(如手机号、邮箱)
    ├── 使用联合主键(除非必要)
    └── 频繁修改主键值

六、外键(Foreign Key)的概念

6.1 什么是外键?

定义:一个表中的字段,引用另一个表的主键,建立两个表之间的关联关系

核心特点

  • 建立表之间的关联
  • 保证数据的一致性
  • 约束数据的完整性

类比理解

  • 外键 ≈ 学生证上的班级编号(关联到班级表)

6.2 外键的作用

code
外键的作用:
│
├── 1⃣ 建立关联关系
│   └── 连接两个表的数据
│
├── 2⃣ 保证数据一致性
│   └── 不能插入不存在的外键值
│
└── 3⃣ 级联操作
    ├── 级联删除(ON DELETE CASCADE)
    └── 级联更新(ON UPDATE CASCADE)

6.3 三种关联关系

6.3.1 一对一关系(1:1)

定义:一个表的记录对应另一个表的一条记录

示例

  • 用户 ↔ 身份证信息
  • 学生 ↔ 学籍档案

实现方式

sql
-- 用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  name VARCHAR(50)
);

-- 身份证信息表(一对一)
CREATE TABLE user_id_cards (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT UNIQUE,  -- UNIQUE 确保一对一
  id_card_no VARCHAR(18),
  FOREIGN KEY (user_id) REFERENCES users(id)
);

ER 图

code
┌─────────┐         ┌──────────────┐
│  用户   │ 1 ──── 1 │ 身份证信息   │
└─────────┘         └──────────────┘

6.3.2 一对多关系(1:N)

定义:一个表的记录对应另一个表的多条记录

示例

  • 用户 ↔ 订单(一个用户多个订单)
  • 班级 ↔ 学生(一个班级多个学生)
  • 用户 ↔ 书本(一个用户多本书)

实现方式

sql
-- 用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  password VARCHAR(255)
);

-- 书本表(一对多)
CREATE TABLE books (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100),
  user_id INT,  -- 外键在"多"的一方
  FOREIGN KEY (user_id) REFERENCES users(id)
);

数据示例

code
用户表(users):
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | zhangsan | 123456   |
+----+----------+----------+

书本表(books):
+----+----------+---------+
| id |   name   | user_id |
+----+----------+---------+
|  1 | 语文书   |    1    |
|  2 | 数学书   |    1    |
|  3 | 英语书   |    1    |
+----+----------+---------+

一个用户(张三)对应多本书(语文、数学、英语)

ER 图

code
┌─────────┐         ┌─────────┐
│  用户   │ 1 ──── N │  书本   │
└─────────┘         └─────────┘

6.3.3 多对多关系(M:N)

定义:一个表的记录对应另一个表的多条记录,反之亦然

示例

  • 用户 ↔ 角色(一个用户多个角色,一个角色多个用户)
  • 学生 ↔ 课程(一个学生多门课程,一门课程多个学生)

实现方式

sql
-- 用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50)
);

-- 角色表
CREATE TABLE roles (
  id INT PRIMARY KEY AUTO_INCREMENT,
  role_name VARCHAR(50)
);

-- 用户角色关联表(多对多)
CREATE TABLE user_roles (
  user_id INT,
  role_id INT,
  PRIMARY KEY (user_id, role_id),  -- 联合主键
  FOREIGN KEY (user_id) REFERENCES users(id),
  FOREIGN KEY (role_id) REFERENCES roles(id)
);

数据示例

code
用户表(users):
+----+----------+
| id | username |
+----+----------+
|  1 | 张三     |
|  2 | 李四     |
+----+----------+

角色表(roles):
+----+------------+
| id | role_name  |
+----+------------+
|  1 | 中队长     |
|  2 | 语文科代表 |
+----+------------+

用户角色关联表(user_roles):
+---------+---------+
| user_id | role_id |
+---------+---------+
|    1    |    1    |  -- 张三 是 中队长
|    1    |    2    |  -- 张三 是 语文科代表
|    2    |    1    |  -- 李四 是 中队长
+---------+---------+

一个用户(张三)有多个角色(中队长、语文科代表)
一个角色(中队长)有多个用户(张三、李四)

ER 图

code
┌─────────┐         ┌─────────────┐         ┌─────────┐
│  用户   │ N ──── M │ 用户角色表  │ M ──── N │  角色   │
└─────────┘         └─────────────┘         └─────────┘

6.4 三种关联关系对比

关系类型表示方法外键位置示例
一对一1:1任一表(加 UNIQUE)用户 ↔ 身份证
一对多1:N"多"的一方用户 ↔ 订单
多对多M:N中间表用户 ↔ 角色
code
三种关系速记:
│
├── 1:1 一对一
│   └── 外键 + UNIQUE
│
├── 1:N 一对多
│   └── 外键在"多"的一方
│
└── M:N 多对多
    └── 中间表 + 联合主键

七、为什么要分表存储?

7.1 问题场景

假设:将书本信息存入用户表

方案一:数组存储

sql
--  不推荐:将书本作为数组存储
CREATE TABLE users_bad (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  books TEXT  -- 存储 JSON 数组:["语文书","数学书","英语书"]
);

问题

  • 数据结构不清晰
  • 不方便索引和查询
  • 修改困难(需要解析 JSON)
  • 关系型数据库不原生支持数组

方案二:冗余字段

sql
--  不推荐:大量冗余数据
CREATE TABLE users_bad (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  book1 VARCHAR(50),  -- 书本1
  book2 VARCHAR(50),  -- 书本2
  book3 VARCHAR(50)   -- 书本3
);

-- 数据示例
+----+----------+--------+--------+--------+
| id | username | book1  | book2  | book3  |
+----+----------+--------+--------+--------+
|  1 | 张三     | 语文书 | 数学书 | 英语书 |
+----+----------+--------+--------+--------+

问题

  • 冗余数据多
  • 扩展性差(书本数量有限)
  • 查询复杂
  • 数据一致性难维护

7.2 正确方案:分表存储

sql
--  推荐:分表存储
-- 用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50)
);

-- 书本表
CREATE TABLE books (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  user_id INT,
  FOREIGN KEY (user_id) REFERENCES users(id)
);

优势

  • 数据结构清晰
  • 方便索引和查询
  • 扩展性强
  • 数据一致性有保障

7.3 分表的好处

code
分表存储的优势:
│
├── 1⃣ 避免数据冗余
│   └── 数据只存储一次,减少存储空间
│
├── 2⃣ 提高查询效率
│   └── 可以建立索引,快速查询
│
├── 3⃣ 保证数据一致性
│   └── 修改一处,所有引用自动更新
│
├── 4⃣ 增强扩展性
│   └── 可以无限扩展关联数据
│
└── 5⃣ 易于维护
    └── 数据独立,修改互不影响

八、索引(Index)的概念

8.1 什么是索引?

定义:数据库中用于提高查询速度的数据结构

类比理解

  • 索引 ≈ 图书馆的目录卡片
  • 索引 ≈ 书本的目录
  • 索引 ≈ 字典的拼音索引

索引原理

code
无索引查询:
遍历所有数据 → 逐条比较 → 时间复杂度 O(n)

有索引查询:
查询索引结构 → 快速定位 → 时间复杂度 O(log n)

8.2 索引的类型

1. 主键索引(自动创建)

sql
-- 主键自动创建索引
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50)
);

2. 唯一索引(UNIQUE)

sql
-- 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

-- 或在表定义时
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  email VARCHAR(100) UNIQUE
);

3. 普通索引(INDEX)

sql
-- 创建普通索引
CREATE INDEX idx_username ON users(username);

-- 或在表定义时
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  INDEX idx_username (username)
);

4. 组合索引

sql
-- 组合索引
CREATE INDEX idx_status_created ON users(status, created_at);

-- 使用原则:最左前缀原则
--  使用索引:WHERE status = 1
--  使用索引:WHERE status = 1 AND created_at > '2024-01-01'
--  不使用索引:WHERE created_at > '2024-01-01'(缺少最左字段)

5. 全文索引(FULLTEXT)

sql
-- 全文索引(用于文本搜索)
CREATE FULLTEXT INDEX idx_content ON articles(content);

-- 使用全文搜索
SELECT * FROM articles WHERE MATCH(content) AGAINST('数据库');

8.3 索引的优缺点

优点

  • 大幅提高查询速度
  • 加速 ORDER BY 和 GROUP BY
  • 提高表连接查询效率

缺点

  • 占用存储空间
  • 降低写入速度(INSERT、UPDATE、DELETE)
  • 需要维护成本

8.4 索引使用原则

code
索引使用原则:
│
├──  应该创建索引的字段
│   ├── 主键(自动创建)
│   ├── 外键(建议创建)
│   ├── 经常查询的字段
│   ├── 经常排序的字段
│   └── 经常作为 WHERE 条件的字段
│
└──  不应该创建索引的字段
    ├── 数据量小的表
    ├── 频繁更新的字段
    ├── 区分度低的字段(如性别、状态)
    └── 很少查询的字段

8.5 查看和删除索引

sql
-- 查看表的索引
SHOW INDEX FROM users;

-- 删除索引
DROP INDEX idx_username ON users;

-- 或使用 ALTER TABLE
ALTER TABLE users DROP INDEX idx_username;

8.6 索引优化示例

sql
-- 场景:查询状态为启用且创建时间在 2024 年的用户

-- 1. 创建组合索引
CREATE INDEX idx_status_created ON users(status, created_at);

-- 2. 查询语句
SELECT * FROM users 
WHERE status = 1 
  AND created_at >= '2024-01-01' 
  AND created_at < '2025-01-01';

-- 3. 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM users WHERE status = 1;

-- 查看是否使用了索引
-- key: idx_status_created(使用了索引)
-- rows: 预估扫描行数

九、关联查询(JOIN)

9.1 什么是关联查询?

定义:通过外键关联,同时查询多个表的数据

9.2 关联查询类型

1. INNER JOIN(内连接)

sql
-- 内连接:只返回两个表中都有匹配的记录
SELECT 
  users.username,
  books.name AS book_name
FROM users
INNER JOIN books ON users.id = books.user_id;

-- 结果:只显示有书本的用户

2. LEFT JOIN(左连接)

sql
-- 左连接:返回左表所有记录,右表没有则为 NULL
SELECT 
  users.username,
  books.name AS book_name
FROM users
LEFT JOIN books ON users.id = books.user_id;

-- 结果:显示所有用户,没有书本的用户显示 NULL

3. RIGHT JOIN(右连接)

sql
-- 右连接:返回右表所有记录,左表没有则为 NULL
SELECT 
  users.username,
  books.name AS book_name
FROM users
RIGHT JOIN books ON users.id = books.user_id;

-- 结果:显示所有书本,没有用户的书本显示 NULL

9.3 多表关联查询示例

sql
-- 三表关联:用户 - 角色 - 权限

SELECT 
  u.username,
  r.role_name,
  p.permission_name
FROM users u
INNER JOIN user_roles ur ON u.id = ur.user_id
INNER JOIN roles r ON ur.role_id = r.id
INNER JOIN role_permissions rp ON r.id = rp.role_id
INNER JOIN permissions p ON rp.permission_id = p.id
WHERE u.id = 1;

9.4 关联查询性能优化

sql
-- 1. 使用索引:确保关联字段有索引
CREATE INDEX idx_user_id ON books(user_id);

-- 2. 只查询需要的字段
SELECT u.username, b.name
FROM users u
INNER JOIN books b ON u.id = b.user_id;

-- 3. 使用表别名
SELECT u.username, b.name
FROM users AS u
INNER JOIN books AS b ON u.id = b.user_id;

-- 4. 避免关联过多表(建议不超过 5 张)

十、最佳实践

10.1 表设计原则

code
表设计原则:
│
├── 1⃣ 范式设计
│   ├── 第一范式:字段不可再分
│   ├── 第二范式:非主键字段完全依赖主键
│   └── 第三范式:非主键字段不传递依赖主键
│
├── 2⃣ 命名规范
│   ├── 表名:小写 + 下划线 + 复数(users、orders)
│   ├── 字段名:小写 + 下划线(user_name、created_at)
│   └── 避免使用保留字
│
├── 3⃣ 字段设计
│   ├── 选择合适的数据类型
│   ├── 设置合理的默认值
│   ├── 添加 NOT NULL 约束
│   └── 添加 COMMENT 注释
│
└── 4⃣ 索引设计
    ├── 主键自动创建索引
    ├── 外键建议创建索引
    ├── 经常查询的字段创建索引
    └── 避免过多索引

10.2 性能优化建议

sql
-- 1. 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM users WHERE status = 1;

-- 2. 避免 SELECT *
SELECT id, username, name FROM users;

-- 3. 使用 LIMIT 分页
SELECT * FROM users LIMIT 0, 10;

-- 4. 使用索引覆盖
CREATE INDEX idx_covering ON users(status, created_at, username);

-- 5. 避免在 WHERE 子句中使用函数
--  不推荐
SELECT * FROM users WHERE YEAR(created_at) = 2024;
--  推荐
SELECT * FROM users 
WHERE created_at >= '2024-01-01' 
  AND created_at < '2025-01-01';

10.3 完整建表示例

sql
-- 用户表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
  username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
  password VARCHAR(255) NOT NULL COMMENT '密码(加密)',
  email VARCHAR(100) UNIQUE COMMENT '邮箱',
  phone CHAR(11) COMMENT '手机号',
  status TINYINT DEFAULT 1 COMMENT '状态:1-启用,0-禁用',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  
  INDEX idx_username (username),
  INDEX idx_email (email),
  INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

-- 订单表
CREATE TABLE orders (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID',
  order_no VARCHAR(50) NOT NULL UNIQUE COMMENT '订单号',
  user_id INT NOT NULL COMMENT '用户ID',
  total_amount DECIMAL(10, 2) NOT NULL COMMENT '订单总金额',
  status TINYINT DEFAULT 0 COMMENT '状态:0-待支付,1-已支付,2-已发货,3-已完成',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  
  FOREIGN KEY (user_id) REFERENCES users(id),
  INDEX idx_user_id (user_id),
  INDEX idx_order_no (order_no),
  INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

十一、常见问题与解决方案

问题原因解决方案
主键冲突插入重复的主键值使用 AUTO_INCREMENT 自动生成
外键约束失败外键值不存在于关联表先插入关联表数据,或取消外键约束
查询速度慢缺少索引或查询复杂添加索引、优化 SQL、使用 EXPLAIN 分析
数据冗余表设计不合理范式设计、分表存储
更新异常数据一致性问题使用事务、外键约束
中文乱码字符集不正确使用 utf8mb4 字符集
磁盘空间不足数据增长快定期清理、数据归档、扩容
死锁事务操作顺序不一致统一操作顺序、减少事务时间

十二、学习要点总结

12.1 核心要点

  1. :数据库存储数据的结构,类似 Excel 表格
  2. :一组相同类型的数据,代表特定含义
  3. 记录:一行完整的、相关的数据
  4. 主键:唯一标识每一行记录的字段,自带索引
  5. 外键:建立表之间关联关系的字段
  6. 三种关系:一对一、一对多、多对多
  7. 索引:提高查询速度的数据结构
  8. 分表:避免数据冗余,提高性能

12.2 记忆技巧

code
记忆技巧:
│
├──  表 ≈ Excel 工作表
├──  列 ≈ 表头字段
├──  记录 ≈ 一行数据
├──  主键 ≈ 身份证号(唯一标识)
├──  外键 ≈ 关联桥梁
├──  索引 ≈ 图书馆目录
│
└── 三种关系
    ├── 1:1 → UNIQUE 外键
    ├── 1:N → 外键在"多"方
    └── M:N → 中间表

12.3 学习路径

code
学习路径规划:
│
├── 第一阶段:理解概念(1-2 天)
│   ├── 理解表、列、记录
│   ├── 理解主键、外键
│   └── 理解三种关联关系
│
├── 第二阶段:实践练习(1 周)
│   ├── 创建数据库和表
│   ├── 实现 CRUD 操作
│   └── 练习关联查询
│
└── 第三阶段:深入应用(持续)
    ├── 索引优化
    ├── 查询优化
    └── 数据库设计

十三、延伸学习资源

13.1 官方文档

13.2 推荐阅读

  • 《MySQL 必知必会》
  • 《高性能 MySQL》
  • 《数据库系统概念》

13.3 练习建议

  1. 基础练习:创建表、插入数据、查询数据
  2. 进阶练习:关联查询、聚合查询、子查询
  3. 实战练习:设计一个完整的用户-订单系统
  4. 优化练习:使用 EXPLAIN 分析查询,优化索引

十四、知识图谱

code
数据库核心概念知识图谱:
│
├── 表(Table)
│   ├── 表名
│   ├── 列/字段
│   └── 行/记录
│
├── 列(Column)
│   ├── 数据类型
│   ├── 约束条件
│   └── 默认值
│
├── 主键(Primary Key)
│   ├── 唯一标识
│   ├── 自带索引
│   ├── 单列主键
│   └── 联合主键
│
├── 外键(Foreign Key)
│   ├── 建立关联
│   ├── 保证一致性
│   └── 级联操作
│
├── 三种关联关系
│   ├── 一对一(1:1)
│   ├── 一对多(1:N)
│   └── 多对多(M:N)
│
├── 索引(Index)
│   ├── 主键索引
│   ├── 唯一索引
│   ├── 普通索引
│   └── 组合索引
│
└── 最佳实践
    ├── 表设计原则
    ├── 性能优化
    └── 查询优化

笔记整理时间:2026-03-07
最后更新时间:2026-03-07