# 一.基础入门
### 1.简介
MySQL 是一个广泛使用的开源关系型数据库管理系统(RDBMS),由瑞典公司 MySQL AB 开发,现属于 Oracle 旗下产品。
核心特点:
**开源免费**
- 社区版(MySQL Community Edition)可免费使用,适合个人和小型企业。
- 企业版提供高级功能和技术支持(需付费)。
**跨平台支持**
- 支持 Windows、Linux、macOS 等多种操作系统。
**高性能**
- 优化了查询处理、索引和存储引擎(如 InnoDB、MyISAM),适合高并发场景。
- 支持事务处理(ACID 兼容),确保数据一致性。
**易用性**
- 使用标准的 SQL 语法,学习成本低。
- 提供丰富的图形化管理工具(如 MySQL Workbench)。
**可扩展性**
- 支持主从复制、集群(MySQL Cluster)、分片(Sharding)等方案,满足大规模数据需求。
**安全性**
- 提供数据加密、用户权限管理、SSL 连接等安全机制。
**与其他数据库对比**
1.MySQL vs PostgreSQL
|对比项| MySQL| PostgreSQL|
|-|-|-|
|类型 |关系型数据库| 关系型数据库(支持扩展类型)|
|事务支持 |支持(InnoDB引擎) |完全支持,ACID 兼容|
|性能 |读写速度快,适合高并发简单查询| 复杂查询优化更好,适合分析场景|
|扩展性| 有限(需通过分片/主从复制)| 更强(支持自定义函数、运算符)|
|JSON支持 |支持(5.7+版本) |更强大(支持JSONB、索引、查询)|
|适用场景 | Web应用、电商、CMS |复杂业务、GIS、数据分析|
|典型用户 |Facebook、Twitter、YouTube| Apple、Spotify、Reddit|
2.MySQL vs MongoDB(非关系型对比)
|对比项 |MySQL |MongoDB|
|-|-|-|
|数据模型 |表结构(行和列) |文档型(JSON格式,无固定Schema)|
|事务支持 |支持 |支持(4.0+版本多文档事务)|
|查询语言 |SQL |NoSQL(类JSON查询语法)|
|扩展性| 垂直扩展(硬件升级) |水平扩展(分片集群)|
|适用场景 |结构化数据、事务操作 |非结构化数据、快速迭代(如日志、IoT)|
|典型用户 |Airbnb、Uber |eBay、Adobe|
3.MySQL vs SQLite
|对比项| MySQL |SQLite|
|-|-|-|
|架构|客户端-服务器模式 |嵌入式(单文件数据库)|
|并发性 |支持多用户高并发| 仅支持单进程访问|
|配置复杂度 |需独立安装和配置|零配置,开箱即用|
|存储限制 |支持TB级数据| 适合小型数据(通常<1TB)|
|适用场景 |多用户Web应用 |移动端App、本地软件(如浏览器缓存)|
|典型用户|WordPress、Joomla| Android、iOS、Chrome|
4.MySQL vs MariaDB
|对比项 |MySQL |MariaDB|
|-|-|-|
|血缘关系 |Oracle维护 |MySQL原团队开发的分支|
|兼容性| 标准MySQL语法 |完全兼容MySQL,新增优化功能|
|性能 |稳定 |部分查询更快(如Aria引擎)|
|开源协议 |部分功能企业版收费 |完全开源|
|适用场景 |企业级稳定需求| 需要免费开源替代方案|
5.MySQL vs Oracle Database
|对比项| MySQL |Oracle Database|
|-|-|-|
|成本 |免费(社区版)| 商业收费,价格高昂|
|功能 |基础功能完善| 企业级功能(如分区表、高级安全)|
|扩展性| 适合中小规模 |支持超大规模集群(如银行系统)|
|适用场景 |中小型企业、初创公司 |大型企业、金融、电信|
6.MySQL vs SQL Server
|对比项 |MySQL |SQL Server|
|-|-|-|
|开发商 |Oracle(原Sun/MySQL AB)| Microsoft|
|许可证| 开源(GPL)/商业版| 商业收费(部分免费版)|
|跨平台支持| 是(Windows/Linux/macOS等) |主要Windows(Linux支持有限)|
|性能 |高并发读写优化 |企业级优化,复杂查询更强|
|扩展性 |垂直扩展为主 |支持分布式、分区表|
|典型用户| Facebook、YouTube、Airbnb |银行、大型企业|
## 2.安装与配置
当前安装教程所使用系统为ubuntu,其他linux类似。windows和mac os 略...
### 2.1 安装MySQL 8
更新软件包列表并安装MySQL服务器
```bash
sudo apt update
sudo apt install mysql-server -y
```
安装完成后,MySQL服务会自动启动。检查状态
```bash
sudo systemctl status mysql
```
### 2.2 运行安全初始化脚本
执行以下命令设置root密码和其他安全选项
```bash
sudo mysql_secure_installation
```
按提示操作:
1.设置root密码。
2.移除匿名用户(选Y)。
3.禁止root远程登录(选Y,后续可通过其他用户远程管理)。
4.移除测试数据库(选Y)。
5.重新加载权限表(选Y)。
### 2.3 配置MySQL允许远程连接
编辑MySQL配置文件
```bash
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
```
找到bind-address并修改为:
```bash
bind-address = 0.0.0.0 # 允许所有IP连接
# 或指定服务器IP,如 bind-address = 192.168.1.100
```
保存后重启MySQL:
sudo systemctl restart mysql
### 2.4 创建远程访问用户并授权
登录MySQL(使用root)
```bash
sudo mysql -u root -p
```
执行以下SQL命令(替换username和password)
密码要求:
•至少包含 1 位大小写
•至少包含 1 位数字
•包含 1 个特殊符号
•必须 8 位及以上
```sql
-- 创建用户(如果允许所有主机访问,用'%'代替'remote_host_ip')
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
-- 授予所有权限(或根据需要限制为特定数据库)
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;
-- 刷新权限
FLUSH PRIVILEGES;
退出MySQL:
EXIT;
```
mysql默认使用3306端口,如果作为远程服务器使用,请配置防火墙打开3306端口。
## 3.数据库基本操作
### 3.1登录 MySQL
```bash
mysql -u 用户名 -p
```
### 3.2 查看所有数据库
```sql
SHOW DATABASES;
```
### 3.3 创建数据库
```sql
CREATE DATABASE 数据库名;
```
### 3.4 选择数据库
```sql
USE 数据库名;
```
### 3.5 删除数据库
```sql
DROP DATABASE 数据库名;
```
### 3.6 查看当前数据库的所有表
```sql
SHOW TABLES;
```
# 二.SQL 语言基础
## 0.数据类型、约束、函数
### 0.1 常用数据类型
整数类型
|类型 |字节 |有符号范围 |无符号范围 |说明|
|-|-|-|-|-|
|TINYINT |1 |-128 ~ 127 |0 ~ 255 |适合布尔值/状态码|
|SMALLINT |2| -32,768 ~ 32,767 |0 ~ 65,535| 适合小型数值范围|
|MEDIUMINT |3 |-8,388,608 ~ 8,388,607 |0 ~ 16,777,215 |中等范围数值|
|INT |4 |-2.14e9 ~ 2.14e9| 0 ~ 4.29e9| 最常用的整数类型|
|BIGINT |8 -9.22e18 ~ 9.22e18 |0 ~ 1.84e19 |适合大整数/ID|
浮点数类型
|类型 |字节 |精度 |特点|
|-|-|-|-|
|FLOAT |4 |约7位有效数字| 单精度浮点数|
|DOUBLE |8| 约15位有效数字 |双精度浮点数|
|DECIMAL| 变长 |精确小数| 适合金融等精确计算场景|
字符串类型
|类型| 最大长度 |说明|
|-|-|-|
|CHAR(n) |255字符 |固定长度,效率高|
|VARCHAR(n) |65,535字节 |可变长度,节省空间|
|TINYTEXT |255字节| 短文本|
|TEXT |65KB| 标准文本内容|
|MEDIUMTEXT |16MB |中等长度文本|
|LONGTEXT| 4GB| 超长文本内容|
日期时间类型
|类型 |格式 |范围 |字节 |说明|
|-|-|-|-|-|
|DATE |YYYY-MM-DD |1000-01-01~9999-12-31 |3 |仅日期|
|TIME |HH:MM:SS[.微秒] |-838:59:59~838:59:59 |3| 时间值|
|DATETIME |YYYY-MM-DD HH:MM:SS |1000-01-01~9999-12-31 |8 |日期+时间|
|TIMESTAMP |YYYY-MM-DD HH:MM:SS |1970-01-01~2038-01-19 |4 |自动转换时区的时间戳|
|YEAR |YYYY| 1901~2155 |1| 年份值|
二进制类型
|类型 |最大长度| 说明|
|-|-|-|
|BINARY(n) |255字节| 固定长度二进制数据|
|VARBINARY(n) |65KB |可变长度二进制数据|
|TINYBLOB| 255字节 |小型二进制对象|
|BLOB |65KB |标准二进制对象|
|MEDIUMBLOB|16MB |中等二进制对象|
|LONGBLOB| 4GB| 大型二进制对象(如图片/文件)|
枚举
```sql
gender ENUM('M','F','U') -- 单选
SET 集合
hobbies SET('音乐','运动','阅读','旅行') -- 多选
```
### 0.2 常用约束条件
列级约束
|约束 |说明| 示例|
|-|-|-|
|PRIMARY KEY |主键 |id INT PRIMARY KEY|
|AUTO_INCREMENT |自增 |id INT AUTO_INCREMENT|
|NOT NULL |非空 |name VARCHAR(50) NOT NULL|
|UNIQUE |唯一| email VARCHAR(100) UNIQUE|
|DEFAULT |默认值 |status INT DEFAULT 1|
|FOREIGN KEY |外键 |user_id INT REFERENCES users(id)|
表级约束
```sql
PRIMARY KEY (列名1, 列名2),
FOREIGN KEY (列名) REFERENCES 外表名(列名),
UNIQUE (列名1, 列名2)
```
### 0.3 函数
#### 0.3.1 字符串函数
基础字符串操作
```sql
CONCAT(str1, str2, ...) -- 连接字符串
LENGTH(str) -- 返回字符串长度(字节数)
CHAR_LENGTH(str) -- 返回字符数
UPPER(str) -- 转为大写
LOWER(str) -- 转为小写
```
字符串截取与处理
```sql
SUBSTRING(str, pos, len) -- 截取子串
LEFT(str, len) -- 从左截取
RIGHT(str, len) -- 从右截取
TRIM([{BOTH|LEADING|TRAILING} [remstr] FROM] str) -- 去除空格/指定字符
REPLACE(str, from_str, to_str) -- 替换字符串
SELECT SUBSTRING('MySQL', 3, 2); -- 返回 'SQ'
SELECT TRIM(LEADING 'x' FROM 'xxxMySQLxxx'); -- 返回 'MySQLxxx'
```
#### 0.3.2 数值函数
基本数学函数
```sql
ABS(x) -- 绝对值
CEIL(x) -- 向上取整
FLOOR(x) -- 向下取整
ROUND(x, d) -- 四舍五入,d为小数位数
MOD(x, y) -- 取模(求余)
RAND() -- 返回0-1随机数
```
数学运算
```sql
POWER(x, y) -- x的y次方
SQRT(x) -- 平方根
EXP(x) -- e的x次方
LOG(x) -- 自然对数
SIN(x), COS(x), TAN(x) -- 三角函数
```
#### 0.3.3 日期时间函数
获取当前时间
```sql
NOW() -- 当前日期和时间
CURDATE() -- 当前日期
CURTIME() -- 当前时间
UNIX_TIMESTAMP() -- 当前UNIX时间戳
```
日期时间计算
```sql
DATE_ADD(date, INTERVAL expr unit) -- 日期加法
DATE_SUB(date, INTERVAL expr unit) -- 日期减法
DATEDIFF(date1, date2) -- 日期差(天数)
TIMESTAMPDIFF(unit, datetime1, datetime2) -- 时间差(指定单位)
SELECT DATE_ADD('2023-01-01', INTERVAL 1 MONTH); -- 返回 '2023-02-01'
SELECT TIMESTAMPDIFF(HOUR, '2023-01-01 08:00:00', '2023-01-01 18:30:00'); -- 返回 10
```
日期时间提取
```sql
YEAR(date) -- 提取年份
MONTH(date) -- 提取月份
DAY(date) -- 提取日
HOUR(time) -- 提取小时
MINUTE(time) -- 提取分钟
SECOND(time) -- 提取秒
```
#### 0.3.4 聚合函数
```sql
COUNT(expr) -- 计数
SUM(expr) -- 求和
AVG(expr) -- 平均值
MAX(expr) -- 最大值
MIN(expr) -- 最小值
```
#### 0.3.5 加密函数
```sql
MD5(str) -- 计算MD5哈希
SHA1(str) -- 计算SHA1哈希
SHA2(str, hash_length) -- 计算SHA2哈希(224/256/384/512)
AES_ENCRYPT(str, key) -- AES加密
AES_DECRYPT(crypt_str, key) -- AES解密
```
#### 0.3.6 系统信息函数
```sql
DATABASE() -- 当前数据库名
USER() -- 当前用户名
VERSION() -- MySQL版本
CONNECTION_ID() -- 连接ID
LAST_INSERT_ID()-- 最后插入的AUTO_INCREMENT值
```
## 1.数据定义语言(DDL)
### 1.1 创建表
[]表示可以不添加
```sql
CREATE TABLE [IF NOT EXISTS] 表名 (
列名1 数据类型 [约束条件],
列名2 数据类型 [约束条件],
...
[表级约束条件]
) [ENGINE=存储引擎] [DEFAULT CHARSET=字符集] [COMMENT='表注释'];
```
```sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
```
### 1.2 查看表结构
```sql
DESC 命令(常用)
DESC 表名;
# 或者 DESCRIBE 表名;
SHOW CREATE TABLE 命令(查看完整建表语句)
SHOW CREATE TABLE 表名;
SHOW INDEX 命令(查看表索引)
SHOW INDEX FROM 表名;
```
### 1.3 修改表结构
#### 1.3.1 添加列
```sql
ALTER TABLE 表名
ADD COLUMN 列名 数据类型 [约束条件] [FIRST|AFTER 列名];
```
```sql
-- 在最后添加列
ALTER TABLE users ADD COLUMN age INT;
-- 在指定位置之后添加列
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;
-- 添加多列
ALTER TABLE users
ADD COLUMN address VARCHAR(100),
ADD COLUMN gender ENUM('M','F') DEFAULT 'M';
```
#### 1.3.2 修改列定义
```sql
ALTER TABLE 表名
MODIFY COLUMN 列名 新数据类型 [约束条件];
```
```sql
-- 修改数据类型
ALTER TABLE users MODIFY COLUMN phone VARCHAR(30);
-- 修改约束条件
ALTER TABLE users MODIFY COLUMN age INT NOT NULL DEFAULT 0;
```
#### 1.3.3 重命名列
```sql
ALTER TABLE 表名
CHANGE COLUMN 旧列名 新列名 数据类型 [约束条件];
ALTER TABLE users CHANGE COLUMN phone mobile VARCHAR(20);
```
#### 1.3.4 删除列
```sql
ALTER TABLE 表名
DROP COLUMN 列名;
----
ALTER TABLE users DROP COLUMN age;
```
#### 1.3.5 重命名表
```sql
ALTER TABLE 旧表名 RENAME TO 新表名;
-- 或
RENAME TABLE 旧表名 TO 新表名;
ALTER TABLE users RENAME TO customers;
-- 或
RENAME TABLE users TO customers;
```
#### 1.3.6 添加索引
```sql
ALTER TABLE 表名
ADD INDEX 索引名 (列名);
ALTER TABLE users ADD INDEX idx_email (email);
```
#### 1.3.7 添加唯一索引
```sql
ALTER TABLE 表名
ADD UNIQUE 索引名 (列名);
ALTER TABLE users ADD UNIQUE uk_username (username);
```
#### 1.3.8 添加主键
```sql
ALTER TABLE 表名
ADD PRIMARY KEY (列名);
ALTER TABLE users ADD PRIMARY KEY (id);
```
#### 1.3.9 删除索引
```sql
ALTER TABLE 表名
DROP INDEX 索引名;
ALTER TABLE users DROP INDEX idx_email;
```
#### 1.3.10 删除主键
```sql
ALTER TABLE 表名
DROP PRIMARY KEY;
```
#### 1.3.11 添加外键约束
```sql
ALTER TABLE 表名
ADD CONSTRAINT 约束名 FOREIGN KEY (列名) REFERENCES 外表名(列名);
----
ALTER TABLE orders
ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id);
```
#### 1.3.12 删除外键约束
```sql
ALTER TABLE 表名
DROP FOREIGN KEY 约束名;
--
ALTER TABLE orders DROP FOREIGN KEY fk_user_id;
```
#### 1.3.13 修改存储引擎
```sql
ALTER TABLE 表名
ENGINE=存储引擎;
--
ALTER TABLE users ENGINE=InnoDB;
```
#### 1.3.14 修改字符集
```sql
ALTER TABLE 表名
CONVERT TO CHARACTER SET 字符集 [COLLATE 排序规则];
```
#### 1.3.15 修改自增值
```sql
ALTER TABLE 表名
AUTO_INCREMENT=新值;
```
### 1.4 删除表
#### 1.4.1 基本删除语法
删除单个表
```sql
DROP TABLE users;
```
安全删除(表不存在时不报错)
```sql
DROP TABLE IF EXISTS users;
```
删除多个表
```sql
DROP TABLE users, orders, products;
```
#### 1.4.2 处理外键约束
先删除外键约束再删表
```sql
-- 查看外键约束名
SHOW CREATE TABLE orders;
-- 删除外键约束
ALTER TABLE orders DROP FOREIGN KEY fk_user_id;
-- 然后删除表
DROP TABLE users;
```
### 1.5 清空表
直接清空
```sql
TRUNCATE TABLE 表名;
```
记录日志清空
```sql
DELETE FROM 表名;
```
## 2.数据操作语言(DML)
### 2.1 插入数据
#### 2.1.1 基本 INSERT 语法
插入单行数据(指定列名)
```sql
INSERT INTO employees (emp_id, name, department, salary)
VALUES (101, '张三', '技术部', 8500.00);
```
插入单行数据(省略列名)
```sql
INSERT INTO departments
VALUES (10, '财务部', '北京');
```
如果插入的表有自增列,获取自增值
```sql
-- 获取最后插入的ID
SELECT LAST_INSERT_ID() AS new_id;
```
#### 2.1.2 插入多行数据
```sql
INSERT INTO products (product_name, price, category)
VALUES
('笔记本电脑', 5999.00, '电子产品'),
('无线耳机', 399.00, '电子产品'),
('办公椅', 899.00, '家具');
```
#### 2.1.3 特殊插入方式
插入查询结果
```sql
INSERT INTO employee_archive (emp_id, name, leave_date)
SELECT emp_id, name, CURDATE()
FROM employees
WHERE status = '离职';
```
使用 SET 语法插入
```sql
INSERT INTO customers
SET
customer_name = '李四',
phone = '13800138000',
email = 'lisi@example.com',
reg_date = NOW();
```
#### 2.1.4 插入时的数据处理
处理 NULL 值
```sql
-- 显式插入NULL
INSERT INTO orders (order_id, product_id, quantity, notes)
VALUES (1001, 5, 2, NULL);
-- 省略列名自动插入NULL(如果列允许NULL)
INSERT INTO orders (order_id, product_id, quantity)
VALUES (1002, 8, 1);
```
使用默认值
```sql
-- 使用DEFAULT关键字
INSERT INTO users (username, password, status)
VALUES ('user1', '123456', DEFAULT);
-- 省略列名使用默认值
INSERT INTO users (username, password)
VALUES ('user2', '654321');
```
使用函数和表达式
```sql
INSERT INTO log_entries (user_id, action, action_time)
VALUES
(101, '登录', NOW()),
(102, '购买', DATE_ADD(NOW(), INTERVAL 1 HOUR));
```
#### 2.1.5 插入时的约束处理
忽略重复键错误
```sql
INSERT IGNORE INTO unique_users (user_id, username)
VALUES (101, 'user1');
```
替换重复记录
```sql
REPLACE INTO product_inventory (product_id, quantity)
VALUES (5, 100);
```
### 2.2 更新数据
#### 2.2.1 基本 UPDATE 用法
更新单表数据
```sql
-- 更新单个字段
UPDATE employees
SET salary = 10000
WHERE emp_id = 101;
-- 更新多个字段
UPDATE products
SET price = price * 0.9,
stock = stock - 1
WHERE product_id = 5;
```
更新所有行(慎用)
```sql
-- 更新表中所有记录(无WHERE条件)
UPDATE users
SET last_login = NOW();
```
#### 2.2.2 条件更新
使用简单条件
```sql
UPDATE orders
SET status = '已完成'
WHERE order_date < '2023-01-01'
AND status = '待处理';
```
使用子查询条件
```sql
-- 更新有订单的客户状态
UPDATE customers
SET is_active = 1
WHERE customer_id IN (
SELECT DISTINCT customer_id
FROM orders
WHERE order_date > '2023-01-01'
);
```
#### 2.2.3 *使用 JOIN 更新
```sql
UPDATE employees e
JOIN departments d ON e.dept_id = d.dept_id
SET e.salary = e.salary * 1.1
WHERE d.location = '上海';
```
#### 2.2.4 基于当前值的更新
```sql
-- 数值增减
UPDATE products
SET view_count = view_count + 1
WHERE product_id = 8;
-- 字符串连接
UPDATE articles
SET content = CONCAT(content, '\n更新于: ', NOW())
WHERE article_id = 15;
```
### 2.3 删除数据
```sql
-- 删除特定ID的记录
DELETE FROM users WHERE user_id = 101;
-- 删除30天未活跃的用户
DELETE FROM customers
WHERE last_login < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 删除表中所有记录(慎用)
DELETE FROM log_entries;
```
## 3.数据查询语言(DQL)
#### 3.1 简单查询
查询所有列
```sql
SELECT * FROM employees;
```
查询特定列
```sql
SELECT first_name, last_name, salary FROM employees;
```
使用列别名
```sql
SELECT first_name AS "名", last_name AS "姓" FROM employees;
```
去除重复值
```sql
SELECT DISTINCT department_id FROM employees;
```
### 3.2 WHERE子句 - 条件过滤
```sql
SELECT * FROM employees WHERE salary > 5000;
```
常用条件运算符:
- 比较运算符:=, <>/!=, >, <, >=, <=
- 逻辑运算符:AND, OR, NOT
- 范围查询:BETWEEN...AND..., NOT BETWEEN...AND...
- 集合查询:IN, NOT IN
- 模糊查询:LIKE, NOT LIKE
- 空值判断:IS NULL, IS NOT NULL
```sql
-- 多个条件
SELECT * FROM employees
WHERE salary BETWEEN 5000 AND 10000
AND department_id = 10;
-- 模糊查询 (%表示任意多个字符,_表示单个字符)
SELECT * FROM employees
WHERE first_name LIKE 'J%';
-- 空值判断
SELECT * FROM employees
WHERE manager_id IS NULL;
```
### 3.3 排序(ORDER BY)
排序默认为ASC(正序),添加DESC变为倒叙
```sql
-- 单列排序
SELECT * FROM employees ORDER BY salary DESC;
-- 单列排序
SELECT * FROM employees ORDER BY salary DESC;
-- 多列排序
SELECT * FROM employees
ORDER BY department_id ASC, salary DESC;
```
### 3.4 分组查询(GROUP BY)
```sql
-- 按部门分组计算平均薪资
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
-- 使用HAVING过滤分组结果
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 5000;
```
### 3.5 分页查询(LIMIT)
```sql
-- 查询前10条记录
SELECT * FROM employees LIMIT 10;
-- 分页查询(第2页,每页10条)
SELECT * FROM employees LIMIT 10 OFFSET 10;
-- 或
SELECT * FROM employees LIMIT 10, 10;
```
### 3.6 多表连接查询(JOIN)
内连接(INNER JOIN)
```sql
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
```
左外连接(LEFT JOIN)
```sql
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;
```
右外连接(RIGHT JOIN)
```sql
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.department_id;
```
交叉连接(CROSS JOIN)
> 返回两表的笛卡尔积(所有可能的组合)
```sql
-- 显式语法
SELECT e.last_name, d.department_name
FROM employees e
CROSS JOIN departments d;
-- 隐式语法
SELECT e.last_name, d.department_name
FROM employees e, departments d;
```
自连接(SELF JOIN)
> 表与自身连接,常用于层级数据(如员工-经理关系)
```sql
SELECT e.employee_id, e.last_name AS employee,
m.last_name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id;
```
### 3.7 子查询
WHERE子句中的子查询
```sql
SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
```
FROM子句中的子查询
```sql
SELECT dept_avg.department_id, dept_avg.avg_salary
FROM (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS dept_avg
WHERE dept_avg.avg_salary > 5000;
```
EXISTS子查询
```sql
SELECT * FROM departments d
WHERE EXISTS (
SELECT 1 FROM employees e
WHERE e.department_id = d.department_id
);
```
### 3.8 联合查询(UNION)
```sql
-- 合并两个查询结果(自动去重)
SELECT employee_id, first_name FROM current_employees
UNION
SELECT employee_id, first_name FROM former_employees;
-- 合并两个查询结果(不去重)
SELECT employee_id, first_name FROM current_employees
UNION ALL
SELECT employee_id, first_name FROM former_employees;
```
### 3.9 提示
1.避免使用SELECT *:只查询需要的列,减少数据传输量
2.合理使用索引:WHERE和JOIN条件中的列最好有索引
3.注意LIKE性能:前导通配符(%xxx)会使索引失效
4.分页优化:大数据量分页使用WHERE id > ? LIMIT ?代替LIMIT offset, size
5.EXPLAIN分析:使用EXPLAIN分析查询执行计划
## 4.数据控制语言(DCL)
数据控制语言(Data Control Language)用于管理数据库访问权限和安全控制。
> 写在前面:修改权限相关操作后记得执行FLUSH PRIVILEGES;刷新权限
### 4.1 用户管理
#### 4.1.1 用户创建与删除
```sql
-- 创建用户(MySQL 5.7+语法)
CREATE USER '用户名'@'主机' IDENTIFIED BY '密码';
-- 删除用户
DROP USER '用户名'@'主机';
```
#### 4.1.2 用户属性修改
```sql
-- 重命名用户
RENAME USER '旧用户'@'主机' TO '新用户'@'新主机';
-- 修改密码
ALTER USER '用户名'@'主机' IDENTIFIED BY '新密码';
-- 设置密码过期
ALTER USER '用户名'@'主机' PASSWORD EXPIRE;
-- 锁定/解锁账户
ALTER USER '用户名'@'主机' ACCOUNT LOCK;
ALTER USER '用户名'@'主机' ACCOUNT UNLOCK;
```
### 4.2 权限管理
#### 4.2.1 权限授予
```sql
-- 基本授权语法
GRANT 权限类型 ON 对象级别 TO '用户'@'主机';
-- 常见权限类型
ALL PRIVILEGES -- 所有权限
SELECT, INSERT, UPDATE, DELETE -- 基本DML
CREATE, ALTER, DROP -- DDL权限
EXECUTE -- 执行存储过程
GRANT OPTION -- 允许转授权
-- 对象级别示例
*.* -- 所有数据库的所有表
数据库名.* -- 指定数据库的所有表
数据库名.表名 -- 指定表
数据库名.存储过程名 -- 指定存储过程
```
#### 4.2.2 权限回收
```sql
REVOKE 权限类型 ON 对象级别 FROM '用户'@'主机';
```
#### 4.2.3 权限查看
```sql
-- 查看用户权限
SHOW GRANTS FOR '用户'@'主机';
-- 查看当前用户权限
SHOW GRANTS;
```
## 5.事务控制(TCL)
事务是数据库操作的最小工作单元,是一组不可分割的SQL操作序列,这些操作要么全部执行成功,要么全部不执行。
### 5.1 事务开启
```sql
-- 标准语法(显式开启事务)
START TRANSACTION;
-- 简写语法
BEGIN;
```
### 5.2 事务提交
```sql
COMMIT;
```
### 5.3 事务回滚
```sql
-- 完全回滚
ROLLBACK;
-- 回滚到特定保存点
ROLLBACK TO SAVEPOINT savepoint_name;
```
### 5.4 保存点管理
```sql
-- 创建保存点
SAVEPOINT savepoint1;
-- 回滚到保存点
ROLLBACK TO SAVEPOINT savepoint1;
-- 释放保存点
RELEASE SAVEPOINT savepoint1;
```