文章目录
- 一、数据库操作
-
- [1. 创建数据库](#1. 创建数据库)
- [2. 查看数据库](#2. 查看数据库)
- [3. 选择数据库](#3. 选择数据库)
- [4. 修改数据库](#4. 修改数据库)
- [5. 删除数据库](#5. 删除数据库)
- [6. 连接数据库](#6. 连接数据库)
- [7. 查看数据库状态](#7. 查看数据库状态)
- [8. 用户管理](#8. 用户管理)
- 二、表操作
-
- [1. 新建表](#1. 新建表)
- [2. 查看表](#2. 查看表)
- [3. 修改表](#3. 修改表)
- [4. 重命名表](#4. 重命名表)
- [5. 复制表](#5. 复制表)
- [6. 删除表](#6. 删除表)
- 三、表数据操作
-
- [1. 表数据插入](#1. 表数据插入)
-
- [1.1 单行插入](#1.1 单行插入)
- [1.2 多行批量插入](#1.2 多行批量插入)
- [1.3 SELECT子查询插入](#1.3 SELECT子查询插入)
- [1.4 重复键处理](#1.4 重复键处理)
- [2. 表数据修改](#2. 表数据修改)
- [3. 表数据删除](#3. 表数据删除)
- [4. 表数据查询](#4. 表数据查询)
-
- [4.1. 基础查询语法](#4.1. 基础查询语法)
- [4.2. 查询所有字段](#4.2. 查询所有字段)
- [4.3. 查询部分字段](#4.3. 查询部分字段)
- [4.4. 条件 WHERE 查询](#4.4. 条件 WHERE 查询)
- [4.5. 关键字 IN 查询](#4.5. 关键字 IN 查询)
- [4.6. 关键字 BETWEEN AND 范围查询](#4.6. 关键字 BETWEEN AND 范围查询)
- [4.7. 关键字 LIKE 模糊匹配](#4.7. 关键字 LIKE 模糊匹配)
- [4.8. 关键字 IS NULL 查询空值](#4.8. 关键字 IS NULL 查询空值)
- [4.9. 关键字 AND 多条件查询](#4.9. 关键字 AND 多条件查询)
- [4.10. 关键字 OR 多条件查询](#4.10. 关键字 OR 多条件查询)
- [4.11. 关键字 DISTINCT 去重](#4.11. 关键字 DISTINCT 去重)
- [4.12. 关键字 GROUP BY 分组查询](#4.12. 关键字 GROUP BY 分组查询)
- [4.13. 关键字 ORDER BY 对查询结果排序](#4.13. 关键字 ORDER BY 对查询结果排序)
- [4.14. 关键字 LIMIT 限制查询结果数量](#4.14. 关键字 LIMIT 限制查询结果数量)
- [4.15. 聚合函数 COUNT() 统计条数](#4.15. 聚合函数 COUNT() 统计条数)
- [4.16. 聚合函数 SUM() 求和](#4.16. 聚合函数 SUM() 求和)
- [4.17. 聚合函数 AVG() 求平均数](#4.17. 聚合函数 AVG() 求平均数)
- [4.18. 聚合函数 MAX() 查询最大值](#4.18. 聚合函数 MAX() 查询最大值)
- [4.19. 聚合函数 MIN() 查询最小值](#4.19. 聚合函数 MIN() 查询最小值)
- [4.20. INNER JOIN 内连接查询](#4.20. INNER JOIN 内连接查询)
- [4.21. LEFT JOIN 左外连接查询](#4.21. LEFT JOIN 左外连接查询)
- [4.22. RIGHT JOIN 右外连接查询](#4.22. RIGHT JOIN 右外连接查询)
- [4.23. 复合条件连接查询](#4.23. 复合条件连接查询)
- [4.24. 带关键字 IN 的子查询](#4.24. 带关键字 IN 的子查询)
- [4.25. 带比较运算符的子查询](#4.25. 带比较运算符的子查询)
- [4.26. 带关键字 EXISTS 的子查询](#4.26. 带关键字 EXISTS 的子查询)
- [4.27. 带关键字 ANY 的子查询](#4.27. 带关键字 ANY 的子查询)
- [4.28. 带关键字 ALL 的子查询](#4.28. 带关键字 ALL 的子查询)
- [4.29. UNION 联合查询](#4.29. UNION 联合查询)
- [4.30. UNION ALL 联合查询](#4.30. UNION ALL 联合查询)
- [4.31. 强制走指定索引](#4.31. 强制走指定索引)
- [4.32. 为表取别名](#4.32. 为表取别名)
- [4.32. 为字段取别名](#4.32. 为字段取别名)
- 四、索引操作
-
- [1. 创建索引](#1. 创建索引)
- [2. 查询索引](#2. 查询索引)
- [3. 删除索引](#3. 删除索引)
- [4. 修改索引](#4. 修改索引)
- 五、视图
-
- [1. 创建视图](#1. 创建视图)
- [2. 查看视图](#2. 查看视图)
- [3. 修改视图](#3. 修改视图)
- [4. 删除视图](#4. 删除视图)
- [5. 视图数据更新](#5. 视图数据更新)
本文将介绍MySQL常用SQL语法,从数据库级别到行数据操作逐一说明他们的使用方法,内容比较多,非常适合新手上手,看完就会mysql开发。
一、数据库操作
1. 创建数据库
sql
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[CHARACTER SET [=] charset_name]
[COLLATE [=] collation_name]
[ENCRYPTION [=] {'Y' | 'N'}]
[READ ONLY [=] {DEFAULT | 0 | 1}];
DATABASE/SCHEMA:同义词,可互换使用。IF NOT EXISTS:避免重复创建时报错(推荐使用)。db_name:数据库名称(需符合标识符规则,长度一般≤64字符)。CHARACTER SET:指定字符集(如utf8mb4、latin1),默认值取决于MySQL版本。COLLATE:指定排序规则(如utf8mb4_bin区分大小写,utf8mb4_general_ci不区分),需与字符集兼容。ENCRYPTION(MySQL 8.0+):启用表空间加密(需InnoDB引擎支持)。READ ONLY(MySQL 8.0+):设置数据库为只读模式(1为只读,0或DEFAULT为可读写)。
示例
sql
CREATE DATABASE IF NOT EXISTS mydb;
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. 查看数据库
sql
-- 查询当前MySQL实例中用户有权限访问的所有数据库。
SHOW DATABASES;
-- 通过通配符匹配数据库名。
SHOW DATABASES LIKE '%db_name%';
-- 查询创建数据库时的完整SQL语句(含字符集和排序规则)。
SHOW CREATE DATABASE db_name;
3. 选择数据库
sql
-- 选择数据库设为当前默认数据库。
use db_name;
4. 修改数据库
sql
ALTER {DATABASE | SCHEMA} [db_name]
[DEFAULT] CHARACTER SET [=] charset_name
[DEFAULT] COLLATE [=] collation_name
[DEFAULT] ENCRYPTION [=] {'Y' | 'N'}
READ ONLY [=] {DEFAULT | 0 | 1};
DATABASE/SCHEMA:同义词,可互换使用。db_name:目标数据库名(省略则修改默认数据库)。CHARACTER SET:指定字符集(如utf8mb4、latin1)。COLLATE:指定排序规则(如utf8mb4_bin区分大小写,utf8mb4_general_ci不区分)。ENCRYPTION(MySQL 8.0+):启用/禁用表空间加密(需InnoDB引擎支持)。READ ONLY:设置数据库为只读模式(1为只读,0或DEFAULT为可读写)。
示例
sql
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
5. 删除数据库
sql
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name;
DATABASE/SCHEMA:同义词,可互换使用。IF EXISTS:避免数据库不存在时报错(推荐使用)。db_name:目标数据库名称(需符合标识符规则,长度一般≤64字符)。
示例
sql
-- 存在则删除,不存在则警告
DROP DATABASE IF EXISTS mydb;
6. 连接数据库
sql
mysql -u [用户名] -p[密码] -h [主机名] -P [端口] [数据库名]
-- MySQL 8.0+语法 无密码登录
mysql -u user --skip-password
示例
sql
mysql -u root -p123456 -h 127.0.0.1 -P 3306 testdb
7. 查看数据库状态
sql
-- 显示所有连接线程
SHOW PROCESSLIST;
-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';
-- 查看数据库端口监听情况
netstat -an | grep 3306
-- 终止某个连接
KILL [连接ID];
8. 用户管理
sql
-- 切换到mysql库
use mysql;
-- 创建用户、设置密码
create user 'testuser'@'%' identified by 'password';
-- `grant`后指定权限列表:SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, EXECUTE等。
-- `grant`语句中的 `on` 后指定作用域:
-- `*.*`表示全局,
-- `testdb.*`表示数据库级,
-- `testdb.users`表示表级。
-- 授权,只给testdb下全部表的select权限
grant select on testdb.* to 'testuser'@'%';
-- 授权,给全部数据库全部全新,慎用!
grant all privileges on *.* to "testuser"@"%";
-- 立即刷新权限
flush privileges;
二、表操作
1. 新建表
sql
CREATE TABLE [IF NOT EXISTS] table_name (
column1 datatype [constraint],
column2 datatype [constraint],
...
[PRIMARY KEY (column1, column2, ...)],
[FOREIGN KEY (column) REFERENCES other_table (other_column)],
[INDEX index_name (column) [USING BTREE | HASH]],
[UNIQUE KEY unique_name (column)],
[CHECK (column_condition)],
[COMMENT '表注释']
)
[ENGINE=storage_engine]
[DEFAULT CHARSET=charset_name]
[COLLATE=collation_name]
[ROW_FORMAT=row_format]
[AUTO_INCREMENT=increment_value];
-
列定义(Column Definition):
- 数据类型 :
INT、VARCHAR(n)、TEXT、DATE、DATETIME、DECIMAL(m,d)、JSON、BLOB等。 - 约束条件 :
NOT NULL:禁止空值。UNIQUE:唯一约束。DEFAULT default_value:默认值。AUTO_INCREMENT:自增属性(通常用于主键)。CHECK (condition):列值校验(MySQL 8.0+ 强制生效)。COMMENT '注释':列注释。
- 数据类型 :
-
主键与索引:
- 主键 :
PRIMARY KEY (column)或PRIMARY KEY (col111, col2)(复合主键)。1, col2)` - 外键 :
FOREIGN KEY (column) REFERENCES parent_table (parent_column)。 - 普通索引 :
INDEX index_name (column)或KEY index_name (column)。 - 唯一索引 :
UNIQUE KEY unique_name (column)。 - 全文索引 :
FULLTEXT INDEX fulltext_name (column)(适用于TEXT类型)。 - 空间索引 :
SPATIAL INDEX spatial_name (column)(适用于GEOMETRY类型)。
- 主键 :
-
表级选项:
- 存储引擎 :
ENGINE=InnoDB(默认,支持事务)、ENGINE=MyISAM(非事务,适合读密集场景)。 - 字符集与排序规则 :
DEFAULT CHARSET=utf8mb4、COLLATE=utf8mb4_unicode_ci。 - 行格式 :
ROW_FORMAT=DYNAMIC(支持大文本)、COMPACT、REDUNDANT。 - 自增起始值 :
AUTO_INCREMENT=1000(设置自增列的起始值)。 - 表注释 :
COMMENT='表描述信息'。
- 存储引擎 :
示例
sql
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
dept_id VARCHAR(10) NOT NULL,
email VARCHAR(100) NOT NULL,
amount DECIMAL(10,2) NOT NULL CHECK (amount > 0),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (dept_id) REFERENCES dept(id),
INDEX idx_email (email)
);
2. 查看表
sql
-- 查看数据库全部表
SHOW TABLES;
-- 查看数据库匹配的表(如以'user'开头的表)
SHOW TABLES LIKE 'user%';
-- 查看当前数据库表结构
DESCRIBE table_name;
-- 查看数据库表结构
SHOW COLUMNS FROM table_name;
-- 查看指定数据库表结构
SHOW COLUMNS FROM db_name.table_name;
-- 获取表的完整创建语句(含索引、约束、引擎等)
SHOW CREATE TABLE table_name;
-- 查看索引信息
SHOW INDEX FROM table_name;
3. 修改表
sql
ALTER TABLE table_name
[ADD COLUMN column_name datatype [constraint] [FIRST | AFTER existing_column]],
[DROP COLUMN column_name],
[MODIFY COLUMN column_name new_datatype [constraint]],
[CHANGE COLUMN old_name new_name new_datatype [constraint]],
[ADD PRIMARY KEY (column1, column2)],
[DROP PRIMARY KEY],
[ADD FOREIGN KEY (column) REFERENCES other_table (other_column)],
[DROP FOREIGN KEY fk_name],
[ADD INDEX index_name (column) [USING BTREE | HASH]],
[DROP INDEX index_name],
[ENGINE=new_engine],
[CHARACTER SET new_charset COLLATE new_collation],
[ROW_FORMAT=new_format],
[AUTO_INCREMENT=new_value],
[COMMENT='new_comment'];
-
列操作:
- 添加列 :
ADD COLUMN age INT DEFAULT 18(可指定位置FIRST或AFTER id)。 - 修改列数据类型 :
MODIFY COLUMN email VARCHAR(200)(需兼容原数据)。 - 重命名列 :
CHANGE COLUMN old_name new_name VARCHAR(100)。 - 删除列 :
DROP COLUMN temp_column(不可恢复)。
- 添加列 :
-
约束管理:
- 主键 :
ADD PRIMARY KEY (id)或DROP PRIMARY KEY(复合主键需同时删除)。 - 外键 :
ADD FOREIGN KEY (user_id) REFERENCES users(id)或DROP FOREIGN KEY fk_order_user。 - 唯一约束 :
ADD UNIQUE (username)。 - 检查约束 (MySQL 8.0+):
ADD CHECK (amount > 0)。
- 主键 :
-
索引操作:
- 创建索引 :
ADD INDEX idx_name (column)(支持BTREE、HASH、FULLTEXT)。 - 删除索引 :
DROP INDEX idx_name(主键索引需用DROP PRIMARY KEY)。 - 强制索引 (MySQL 8.0+):
ALTER TABLE ... INDEX [IF NOT EXISTS] index_name {VISIBLE | INVISIBLE}。
- 创建索引 :
-
表级属性修改:
- 存储引擎 :
ENGINE=InnoDB(支持事务)或ENGINE=MyISAM(非事务)。 - 字符集与排序规则 :
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。 - 行格式 :
ROW_FORMAT=DYNAMIC(支持大文本)或COMPACT。 - 自增值重置 :
AUTO_INCREMENT=1000。 - 表注释 :
COMMENT='用户订单表'。
- 存储引擎 :
示例
sql
-- 添加字段
ALTER TABLE users ADD COLUMN created_time DATETIME DEFAULT CURRENT_TIMESTAMP;
-- 修改字段
ALTER TABLE users MODIFY COLUMN amount DECIMAL(10,4) NOT NULL CHECK (amount > 0);
-- 删除字段
ALTER TABLE users drop COLUMN amount;
4. 重命名表
sql
-- 单表重命名
RENAME TABLE old_table TO new_table;
-- 多表批量重命名
RENAME TABLE old1 TO new1, old2 TO new2;
-- 使用ALTER语法重命名
ALTER TABLE old_table RENAME TO new_table;
-- 或(语法等效)
ALTER TABLE old_table RENAME AS new_table;
5. 复制表
sql
-- 创建结构相同的空表,不复制数据
CREATE TABLE new_table LIKE old_table;
-- 复制表结构和所有数据,但不复制索引、约束、触发器。
CREATE TABLE new_table AS SELECT * FROM old_table;
-- 只复制表数据
INSERT INTO target_table (col1, col2) SELECT col1, col2 FROM source_table;
6. 删除表
sql
DROP [TEMPORARY] TABLE [IF EXISTS] table_name [, table_name2, ...]
[RESTRICT | CASCADE];
TEMPORARY:可选关键字,用于删除临时表(如DROP TEMPORARY TABLE temp_table)。IF EXISTS:避免表不存在时报错(推荐使用),仅触发警告(Warning)。- 多表批量删除 :支持逗号分隔多表名(如
DROP TABLE table1, table2)。 RESTRICT/CASCADE:MySQL中无实际作用(保留兼容性),但需注意外键依赖。
示例
sql
-- 直接删除
DROP TABLE users;
-- 存在则删除,不存在则警告
DROP TABLE IF EXISTS users;
-- 批量删除表
DROP TABLE orders, customers, products;
-- 删除临时表
DROP TEMPORARY TABLE IF EXISTS temp_logs;
三、表数据操作
1. 表数据插入
1.1 单行插入
sql
INSERT INTO table_name (col1, col2, ...) VALUES (val1, val2, ...);
- 列顺序与默认值 :未指定的列使用默认值(如
NOT NULL列需显式赋值或配置默认值)。 - 自增列处理 :
AUTO_INCREMENT列可省略,系统自动生成唯一值(如id INT AUTO_INCREMENT)。
1.2 多行批量插入
单条INSERT多行比多条单行插入效率更高(减少事务开销)。
sql
INSERT INTO table_name (col1, col2)
VALUES
(val1a, val2a),
(val1b, val2b);
1.3 SELECT子查询插入
结合JOIN或聚合函数实现复杂数据迁移,实现跨表复制。
sql
INSERT INTO target_table (col1, col2)
SELECT source_col1, source_col2
FROM source_table
WHERE condition;
1.4 重复键处理
sql
-- 忽略重复(MySQL 8.0+)
INSERT IGNORE INTO table_name ... ;
-- 主键冲突时更新(ON DUPLICATE KEY UPDATE)
INSERT INTO table_name (id, col)
VALUES (1, 'new_val')
ON DUPLICATE KEY UPDATE col = 'updated_val';
2. 表数据修改
sql
UPDATE [LOW_PRIORITY] [IGNORE] table_name
SET
column1 = {expr1 | DEFAULT},
column2 = {expr2 | DEFAULT},
...
[WHERE conditions]
[ORDER BY column [ASC | DESC]]
[LIMIT row_count]
[FOR UPDATE | LOCK IN SHARE MODE]; -- 事务锁机制
-
条件控制:
WHERE:精确控制更新范围(无WHERE则更新全表,慎用!)。LIMIT:限制更新行数(如LIMIT 1000),结合ORDER BY确定更新顺序。IGNORE:忽略更新中的错误(如唯一键冲突),仅警告不中断。
-
锁机制:
LOW_PRIORITY:降低UPDATE操作优先级,等待所有读(SELECT)操作完成后再执行。FOR UPDATE:行级排他锁,防止其他事务修改选中行(需事务支持)。LOCK IN SHARE MODE:行级共享锁,允许其他事务读取但禁止修改。
-
默认值处理:
SET column = DEFAULT:重置列为默认值(需列定义包含DEFAULT)。
示例
sql
-- 单表更新
UPDATE products
SET price = price * 0.9
WHERE category = 'seasonal' AND stock > 100;
-- 基于子查询更新
UPDATE employees e
SET bonus = (SELECT AVG(salary) FROM managers WHERE dept = e.dept);
-- 多表联合更新
UPDATE orders o
INNER JOIN customers c ON o.cust_id = c.id
SET o.country = c.country
WHERE c.country = 'Germany';
3. 表数据删除
sql
DELETE [LOW_PRIORITY] [IGNORE] FROM table_name
[WHERE conditions]
[ORDER BY column]
[LIMIT row_count]
[FOR UPDATE | LOCK IN SHARE MODE]; -- 事务锁控制
-
条件控制:
WHERE:精确删除范围(无WHERE则删除全表,慎用!)。LIMIT:分批删除避免长事务锁(如LIMIT 10000)。IGNORE:忽略删除中的错误(如唯一键冲突),仅警告不中断。
-
锁机制:
LOW_PRIORITY:降低删除操作优先级,等待读操作完成后再执行。FOR UPDATE/LOCK IN SHARE MODE:显式控制事务锁级别。
示例
sql
-- 单表删除
DELETE FROM users WHERE status = 'inactive';
-- 分批次删除
DELETE FROM large_table WHERE condition LIMIT 10000;
-- 多表联合删除
DELETE o
FROM orders o
INNER JOIN customers c ON o.cust_id = c.id
WHERE c.country = 'Germany';
-- 表级清空效率最好
TRUNCATE TABLE users;
4. 表数据查询
4.1. 基础查询语法
sql
SELECT [DISTINCT] column1, column2, ...
FROM table_name
[WHERE conditions]
[GROUP BY column]
[HAVING group_conditions]
[ORDER BY column [ASC|DESC]]
[LIMIT offset, row_count]
[FOR UPDATE | LOCK IN SHARE MODE]; -- 事务锁控制
-- 示例
SELECT id, username, email
FROM users
WHERE status = 'active'
GROUP BY department
HAVING COUNT(*) > 10
ORDER BY created_at DESC
LIMIT 100;
4.2. 查询所有字段
sql
SELECT * FROM table_name;
4.3. 查询部分字段
sql
-- 查询单个字段
SELECT column_name FROM table_name;
-- 查询多个字段
SELECT column_name1,column_name2 FROM table_name;
4.4. 条件 WHERE 查询
sql
SELECT * FROM table_name WHERE user_id ='XXXX';
4.5. 关键字 IN 查询
sql
SELECT * FROM table_name WHERE user_id IN('XXX1','XXX2');
SELECT * FROM table_name WHERE user_id NOT IN('XXX1','XXX2');
4.6. 关键字 BETWEEN AND 范围查询
查询范围内数据,闭区间范围,包含头尾。
sql
SELECT * FROM table_name WHERE age BETWEEN 0 AND 18;
4.7. 关键字 LIKE 模糊匹配
使用通配符模糊匹配查询。
sql
SELECT * FROM table_name WHERE user_name LIKE 'tom%';
4.8. 关键字 IS NULL 查询空值
sql
-- 查询空值
SELECT * FROM table_name WHERE user_name IS NULL;
-- 查询非空
SELECT * FROM table_name WHERE user_name IS NOT NULL;
4.9. 关键字 AND 多条件查询
可以追加多个AND条件,全部条件必须同时满足。
sql
SELECT * FROM table_name WHERE user_name = 'tom' AND age = 18;
4.10. 关键字 OR 多条件查询
可以追加多个OR条件,只满足其中一个条件就可以。
sql
SELECT * FROM table_name WHERE user_name = 'tom' OR age = 18;
4.11. 关键字 DISTINCT 去重
对字段去重,可以是多个。
sql
SELECT DISTINCT user_name FROM table_name;
SELECT DISTINCT user_id,user_name FROM table_name;
4.12. 关键字 GROUP BY 分组查询
对查询数据进行分组。
sql
SELECT COUNT(*),age FROM table_name WHERE age > 18 GROUP BY age;
4.13. 关键字 ORDER BY 对查询结果排序
对查询结果进行排序。ASC表示升序,DESC表示倒序
sql
SELECT * FROM table_name WHERE age > 18 ORDER BY age;
4.14. 关键字 LIMIT 限制查询结果数量
sql
-- LIMIT 10 表示取前10条
SELECT * FROM table_name WHERE age > 18 ORDER BY age LIMIT 10;
-- LIMIT 10,20 表示从编号10开始取20条
SELECT * FROM table_name WHERE age > 18 ORDER BY age LIMIT 10,20;
4.15. 聚合函数 COUNT() 统计条数
COUNT(*)内部已优化,速度最快。返回复合条件的行数数量。
sql
SELECT COUNT(*),age FROM table_name WHERE age > 18 GROUP BY age;
4.16. 聚合函数 SUM() 求和
sql
SELECT SUM(money) FROM table_name;
4.17. 聚合函数 AVG() 求平均数
sql
SELECT AVG(money) FROM table_name;
4.18. 聚合函数 MAX() 查询最大值
sql
SELECT MAX(money) FROM table_name;
4.19. 聚合函数 MIN() 查询最小值
sql
SELECT MIN(money) FROM table_name;
4.20. INNER JOIN 内连接查询
默认连接类型,返回两个表中满足连接条件的匹配行,不匹配的行会被过滤。
sql
SELECT o.order_id, c.customer_name
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id;
4.21. LEFT JOIN 左外连接查询
返回左表的所有行,即使右表无匹配。右表无匹配时,对应字段显示为NULL。
sql
SELECT c.customer_name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id;
4.22. RIGHT JOIN 右外连接查询
返回右表的所有行,即使左表无匹配。左表无匹配时,对应字段显示为NULL。
sql
SELECT o.order_id, c.customer_name
FROM orders o
RIGHT JOIN customers c ON o.customer_id = c.customer_id;
4.23. 复合条件连接查询
通过多个条件或混合连接类型实现复杂查询逻辑。
sql
SELECT c.customer_name, o.order_id, d.product
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id -- 左连接保留客户
AND c.city = o.ship_city; -- 额外条件
JOIN order_details d ON o.order_id = d.order_id; -- 内连接过滤有效订单
4.24. 带关键字 IN 的子查询
查询匹配子查询返回结果的所有记录。
sql
SELECT * FROM users WHERE user_id IN (SELECT user_id FROM dept WHERE dept_id='101');
4.25. 带比较运算符的子查询
查询比子查询结果大的记录。
sql
SELECT user_id,user_name FROM users WHERE user_id >= (SELECT MAX(user_id) FROM dept WHERE dept_id='101');
4.26. 带关键字 EXISTS 的子查询
查询复合条件且存在于子查询中的记录。
sql
SELECT * FROM users WHERE user_id EXISTS (SELECT user_id FROM dept WHERE dept_id='101');
SELECT * FROM users WHERE user_id>=10 AND EXISTS (SELECT user_id FROM dept WHERE dept_id='101');
4.27. 带关键字 ANY 的子查询
表示满足子查询的任意一个条件即可。
sql
SELECT * FROM users WHERE user_id < ANY (SELECT user_id FROM dept WHERE dept_id='101');
4.28. 带关键字 ALL 的子查询
表示需要满足子查询的全部条件。
sql
SELECT * FROM users WHERE user_id < ALL (SELECT user_id FROM dept WHERE dept_id='101');
4.29. UNION 联合查询
合并查询结果,去重。
sql
SELECT user_id FROM users
UNION
SELECT user_id FROM dept;
4.30. UNION ALL 联合查询
合并查询结果,不会去重。
sql
SELECT user_id FROM users
UNION ALL
SELECT user_id FROM dept;
4.31. 强制走指定索引
强制sql走指定的索引。
sql
SELECT * FROM users FORCE INDEX (index_name);
4.32. 为表取别名
为表指定一个别名,方便阅读、使用。
sql
SELECT * FROM users t WHERE t.user_id = '001';
4.32. 为字段取别名
为字段指定一个别名,可自定义数据库和应用端的字段映射。
sql
SELECT user_id AS id, user_name AS name FROM users;
四、索引操作
1. 创建索引
1.1 使用 CREATE INDEX 创建
sql
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON table_name (column_name [(length)] [ASC|DESC], ...)
[USING {BTREE|HASH}];
示例
sql
-- 普通索引(BTREE默认)
CREATE INDEX idx_email ON users(email); -- 前缀索引,仅索引前20字符
-- 唯一索引
CREATE UNIQUE INDEX idx_phone ON users(amount);
1.2 建表时创建
sql
-- 建表时添加主键索引
CREATE TABLE comprehensive_demo (
-- 主键索引(聚簇索引,唯一非空)
id INT AUTO_INCREMENT PRIMARY KEY,
-- 唯一索引(自动约束phone唯一)
phone VARCHAR(20) NOT NULL UNIQUE,
-- 普通索引(前缀索引,仅索引email前20字符)
email VARCHAR(100) NOT NULL,
INDEX idx_email (email(20)),
-- 复合索引(last_name升序 + first_name升序 + age降序,MySQL 8.0+支持降序)
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
age INT NOT NULL,
INDEX idx_name_age (last_name, first_name, age DESC),
-- 全文索引(中文支持,需配置ngram分词器)
content TEXT NOT NULL,
FULLTEXT INDEX idx_content (content) WITH PARSER ngram,
-- 空间索引(地理数据,需GEOMETRY类型)
coords GEOMETRY NOT NULL,
SPATIAL INDEX idx_coords (coords),
-- 其他字段
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
1.3 使用 ALTER TABLE 创建
sql
ALTER TABLE table_name
ADD [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING {BTREE|HASH}]
(column_name [(length)] [ASC|DESC], ...);
示例
sql
-- 添加联合索引
ALTER TABLE users ADD INDEX idx_name_age (last_name, age);
2. 查询索引
sql
-- 显示索引名、类型、列名、唯一性等
SHOW INDEX FROM table_name;
-- 查看建表语句中的索引定义
SHOW CREATE TABLE table_name;
-- 查询系统表
SELECT INDEX_NAME, COLUMN_NAME, SEQ_IN_INDEX
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name';
3. 删除索引
需具有ALTER或DROP权限,大表删除索引可能锁表,建议在低峰期操作。
sql
-- 直接删除,推荐
DROP INDEX index_name ON table_name;
-- 更新表方式删除
ALTER TABLE table_name DROP INDEX index_name;
-- 删除主键索引
ALTER TABLE table_name DROP PRIMARY KEY;
-- 若主键是自增列(AUTO_INCREMENT),需先移除自增属性
ALTER TABLE table_name MODIFY id INT; -- 移除自增属性
ALTER TABLE table_name DROP PRIMARY KEY;
4. 修改索引
MySQL中没有直接修改索引的语法(如修改索引类型、列顺序等),需通过删除旧索引+创建新索引实现。
sql
-- 删除
DROP INDEX idx_name ON table_name;
-- 创建
CREATE UNIQUE INDEX idx_name ON table_name (column);
五、视图
视图(View)是基于SQL查询结果的虚拟表,不存储实际数据,常用于简化复杂查询、权限控制或数据抽象。
1. 创建视图
sql
CREATE [OR REPLACE] VIEW view_name
[(column_name1, column_name2, ...)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION];
参数说明:
OR REPLACE:若视图已存在则替换(需相同DEFINER权限)。column_name:显式指定视图列名(可选,不指定时使用查询字段别名)。select_statement:查询语句(支持JOIN、WHERE、GROUP BY等)。WITH CHECK OPTION:确保通过视图修改的数据符合视图条件(如WHERE department='IT')。
示例:
sql
-- 简单视图(基于单表)
CREATE VIEW v_employees AS
SELECT id, name, salary
FROM employees WHERE status = 'active';
-- 复合视图(多表JOIN+计算列)
CREATE VIEW v_sales_summary AS
SELECT
o.order_id,
c.customer_name,
SUM(o.amount) AS total_sales,
COUNT(*) AS order_count
FROM orders o
JOIN customers c ON o.customer_id = c.id
GROUP BY o.order_id, c.customer_name;
2. 查看视图
查看视图定义
sql
-- 直接查询创建视图的定义
SHOW CREATE VIEW view_name;
-- 从系统表查询视图定义
SELECT VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'view_name';
查看视图结构与列信息
sql
-- 查看视图列名、类型、是否允许NULL等
DESCRIBE view_name;
-- 等价操作
SHOW COLUMNS FROM view_name;
--从系统表查询
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'view_name';
查看视图依赖关系
sql
-- 追踪视图引用的表或其他视图。
SELECT TABLE_NAME AS BASE_TABLE
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE
WHERE VIEW_SCHEMA = 'db_name' AND VIEW_NAME = 'view_name';
-- MySQL 8.0+支持此功能,展示视图间的层级依赖。
SELECT *
FROM INFORMATION_SCHEMA.VIEW_DEPENDENCIES
WHERE VIEW_SCHEMA = 'db_name' AND VIEW_NAME = 'view_name';
查看视图属性
sql
-- 算法与检查选项
SELECT ALGORITHM, CHECK_OPTION
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = 'view_name';
-- 全新信息
SELECT DEFINER, SQL_SECURITY
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = 'view_name';
3. 修改视图
视图若包含以下结构,则不可更新,需重新创建新视图:
- 聚合函数(SUM/COUNT)、
DISTINCT、GROUP BY、HAVING、UNION。 - 子查询、多表JOIN、临时表算法(
TEMPTABLE)。
使用 CREATE OR REPLACE VIEW 修改视图
若视图存在则替换,不存在则创建。支持指定算法、列名和检查选项:
sql
CREATE [OR REPLACE] [ALGORITHM={MERGE|TEMPTABLE|UNDEFINED}]
VIEW view_name [(column_name1, column_name2, ...)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION];
示例:
sql
-- 替换视图并添加部门字段
CREATE OR REPLACE VIEW v_employees AS
SELECT id, name, salary, department
FROM employees WHERE status = 'active';
使用 ALTER VIEW 修改视图
直接修改现有视图定义,语法与 CREATE VIEW 类似:
sql
ALTER [ALGORITHM={MERGE|TEMPTABLE|UNDEFINED}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION];
示例:
sql
-- 修改视图查询逻辑
ALTER VIEW v_sales_summary AS
SELECT product_id, SUM(amount) AS total
FROM orders GROUP BY product_id;
4. 删除视图
sql
-- MySQL5.7+推荐方式。只删除视图,不会删除依赖管理数据
DROP VIEW [IF EXISTS] view_name;
-- 视图存在则删除,不存在则静默跳过。
DROP VIEW IF EXISTS v_employees;
-- MySQL 8.0+ 级联删除视图
DROP VIEW [IF EXISTS] view_name RESTRICT; -- 默认,禁止删除依赖对象
DROP VIEW [IF EXISTS] view_name CASCADE; -- 级联删除依赖视图(谨慎使用)
5. 视图数据更新
视图可以用于查询操作,但并非所有视图都支持插入、更新和删除(DML操作),这主要取决于视图的定义。如果视图包含了GROUP BY、DISTINCT、JOIN或者UNION等聚合或复杂操作,可能无法直接进行修改。
视图可更新的必要条件
- 来源表为基表:不能基于其他视图或复杂查询(如JOIN、子查询)。
- 包含所有主键列:确保数据唯一性。
- 无聚合/分组操作:禁止使用SUM、COUNT、DISTINCT、GROUP BY、HAVING。
- 无不可更新结构:如UNION、临时表算法(TEMPTABLE)、子查询。
- 算法为MERGE:默认算法,将视图查询合并到基表执行。
- 检查选项生效 :若定义时包含
WITH CHECK OPTION,更新数据必须符合视图条件(如WHERE department='IT')。
可更新视图示例
sql
-- 创建可更新视图
CREATE VIEW emp_view AS
SELECT id, name, salary FROM employees WHERE dept_id = 10;
-- 更新视图(实际更新基础表)
UPDATE emp_view SET salary = 5000 WHERE id = 100;
不可更新视图示例
sql
-- 不可更新视图(包含聚合)
CREATE VIEW dept_avg_salary AS
SELECT dept_id, AVG(salary) AS avg_salary FROM employees GROUP BY dept_id;
-- 尝试更新会报错
UPDATE dept_avg_salary SET avg_salary = 5000; -- 错误:视图不可更新
错误提示:Error Code: 1288. The target table 'dept_avg_salary' of the INSERT/UPDATE is not updatable。