2037 字
10 分钟
mysql基础

什么是 MySQL#

MySQL 是一个高性能,开源的关系型数据库管理系统 (RDBMS)。使用 SQL (Structured Query Language) 进行数据查询,数据以表的形式(行和列)进行存储。

数据会以文件的形式存储到磁盘中,根据不同的存储引擎会有不同的存储策略,现在大多数是使用 InnoDB 引擎。

但是如果每次数据操作都直接读写磁盘,效率会非常低,因此 InnoDB 会在内存中开辟一块称作缓冲池的空间,每次读写操作都会通过缓冲池进行,大大的提高了效率。

核心概念#

在 MySQL 的存储逻辑中,有几个核心的概念:

  • 数据库 (Database):存储和管理数据的容器
  • 表 (Table): 实际存放数据的结构,由行和列组成
  • 行 (Row): 表示具体的一条数据
  • 列 (Column) / 字段 (Field): 表示数据的属性
  • 主键 (Primary Key): 一条数据的唯一(不能重复)标识,不能为空
  • 外键 (Foreign Key): 用于在表与表之间建立联系的标识,通常是另一张表的主键或唯一键。当前表中通过外键记录关联表的主键值,从而建立联系

一些基础 SQL 语法#

DDL (Data Definition Language - 数据定义语言)#

用于对数据库对象(比如数据库、表、视图、索引、存储) 进行增删改操作 (操作隐性提交,不能回滚)

-- 1. 查看数据库
SHOW DATABASES;
-- 2. 创建一个名为 demo 的数据库
CREATE DATABASE demo;
-- 3. 切换到 demo 这个数据库 (后续能操作这个数据库)
USE demo;
-- 4. 显示当前数据库中的表
SHOW TABLES;
-- 5. 创建一张表
-- id 大整型(BIGINT) 设定为主键(PRIMARY KEY) 值自增(AUTO_INCREMENT)
-- name password 可变字符串(VARCHAR) 不能为空(NOT NULL)
-- create_time 时间戳(TIMESTAMP) 默认为数据创建时的时间(DEFAULT CURRENT_TIME)
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- 6. 查看表结构
DESCRIBE users; -- 也可以简写为 DESC users;
-- 7. 删除表
DROP TABLE users;
-- 8. 删除数据库
DROP DATABASE demo;
-- 9. 修改表结构
-- 10. 例如将 users 表中 password 改为 user_password 并且类型改为 varchar(32)
ALTER TABLE users CHANGE COLUMN password user_password VARCHAR(32) NOT NULL;

DML (Data Manipulation Language - 数据操作语言)#

用于对表中的数据进行增、删、改操作

-- 1. 插入数据 (INSERT)
-- id 字段自增,可以不用填写 (实际上密码一般都是加密存储的)
-- create_time 字段有默认值,也可以不用填写
-- 注意:列名列表和 VALUES 中的值必须一一对应
INSERT INTO users (name, password) VALUES ('admin', '12345678');
-- 也可以直接插入
-- 但是必须提供所有字段,对于自增和有默认值的可以用 DEFAULT 让系统自动生成
INSERT INTO users VALUES (DEFAULT, 'user_001', '87654321', DEFAULT);
-- 2. 修改数据 (UPDATE)
-- 将用户名为 'admin' 的用户密码改为 '11223344'
-- 如果不加 WHERE 限定会改掉所有用户的密码
UPDATE users SET password = '11223344' WHERE name = 'admin';
-- 3. 删除数据 (DELETE)
-- 删除名字为 'user_001' 的用户
-- 如果不加 WHERE 限定会删掉所有用户(DELETE FROM users -- 清空表,但保留表结构)
DELETE FROM users WHERE name = 'user_001';
PS. 一定要注意 WHERE 的使用,一不小心就把整张表所有数据改掉了

DQL (Data Query Language - 数据查询语言)#

用于查询数据库中的数据

-- 1. 查询所有行
SELECT * FROM users;
-- 2. 查询指定列 (又称投影查询)
SELECT name, password FROM users;
-- 3. 带条件查询 (WHERE)
SELECT * FROM users WHERE create_time > '2026-02-23';
-- 4. 排序(ORDER BY 默认升序)
SELECT * FROM users ORDER BY create_time;
-- 降序 (DESC)
SELECT * FROM users ORDER BY create_time DESC;
-- 5. 限制返回行数 (LIMIT)
-- 只返回两行
SELECT * FROM users LIMIT 2;
-- 结合排序和限制,查询最早注册的用户
SELECT * FROM users ORDER BY create_time LIMIT 1;
-- 6. 模糊查询 (LIKE)
-- '%'代表匹配多个任意字符 '_'代表匹配一个任意字符
SELECT * FROM users WHERE name LIKE '%d%';
SELECT * FROM users WHERE name LIKE '__e%';
-- 7. 去重 (DISTINCT)
-- 查看有叫哪些名字的 (把重复的名字去掉了)
SELECT DISTINCT name FROM users;

一些进阶 SQL 语法#

分页查询#

在数据量很多的时候,进行大量查询时通常会进行分页操作

-- 基于 LIMIT 加上偏移量 OFFSET 进行分页操作
-- 没有加上 OFFSET 的时候其实就是相当于 OFFSET = 0
SELECT * FROM users LIMIT 5;
SELECT * FROM users LIMIT 5 OFFSET 0;
-- 正常我们看分页数据都是有两个指标:页长(pageSize)和页码(pageNum)
-- 页长就是每页有多少个数据,页码就是当前第几页
-- 本质上 LIMIT N 和 OFFSET M 的组合就是获取 范围为第M+1~M+N的所有数据
-- 页长和页码同偏移量之间的转换则就是: offset = pageSize * (pageNum - 1)
-- 例如当页长为10,查询第5页
SELECT * FROM users LIMIT 10 OFFSET 40;

聚合查询#

SQL 提供了一些用于统计和计算的聚合函数,例如:

-- 用于统计数量的 COUNT(),其结果返回一个一行一列的二维表
-- 列名为填写的 COUNT(*) , 对应的数据为统计的数量
-- * 替换成表中其他字段效果也等同,都是统计这个表的行数
SELECT COUNT(*) FROM users;
-- 用于计算数值和的 SUM() 计算的字段必须为数值类型
-- 返回形式和COUNT()相似
-- 假设users 存在数值字段 age
-- 计算用户年龄总和 (好像没啥实际意义)
SELECT SUM(age) FROM users;
-- 用于计算最大值的 MAX()
-- 计算的字段不局限于数值,字符类型也可以,其大小以字典序决定
-- 返回形式同上
-- 计算用户的最大年龄
SELECT MAX(age) FROM users;
-- 用于计算最小值的 MIN()
-- 形式同 MAX()
SELECT MIN(age) FROM users;
-- 用于分组的 GROUP BY
-- 假设 users 存在角色字段 role
-- 这里的 num 是给结果列名 COUNT(*) 改名为 num 上述也能进行这种操作
-- 这里是将 users 按 role 分组后分别统计数量,结果返回一个多行一列的结果
-- 每行对应每个角色分组的统计数量
SELECT COUNT(*) num FROM users GROUP BY role;

多表查询#

SELECT 查询可以从多张表同时查询数据,实际业务上也是多表查询居多

-- 1. 直接多表查询
-- 直接查询多个表
-- 返回一个 users 和 roles 表的"乘积表" (集合论中的笛卡尔积)
SELECT * FROM users, roles;
-- 直接查询多个表的指定字段的
-- 就是上面那个乘积里选出几列
-- 指定字段用了【表名.字段名】的形式表示具体指哪个表中的字段
-- 这里用了在数据对象后面取别名的方法,在复杂查询中能简化许多
SELECT
u.id uid, u.name uname, r.id rid, r.name rname
FROM
users u, roles r;
-- 2. 内连接多表查询
-- 假设 roles 表存储 (id, user_id, role_name)
-- 现在要查询出用户信息和对应的角色的表
-- 使用 INNER JOIN 进行连接,结果会返回上述"乘积"中,符合 u.id = r.user_id的
SELECT
u.id, u.name, u.password ,r.role_name
FROM
users u INNER JOIN roles r
ON
u.id = r.user_id;
-- 3. 外连接多表查询
-- 外连接有左外连接(LEFT JOIN),右外连接(RIGHT JOIN)查询 (外 OUTER 通常会被省略)
-- 对于左外连接,就是以左表为主表,将右表存在关联的数据连接上,其他用 NULL 补全
SELECT
u.id, u.name, u.password ,r.role_name
FROM
users u LEFT JOIN roles r
ON
u.id = r.user_id;
-- 对于右外连接,则是以右表为主表,将左表存在关联的数据连接上,其他用 NULL 补全
SELECT
u.id, u.name, u.password, r.role_name
FROM
users u RIGHT JOIN rules r
ON
u.id = r.user_id;
-- 以及全外连接 (FULL JOIN),但是在 Mysql 里没有这个语法
-- 实际上相当于将 左右连接 UNION 起来
SELECT
u.id, u.name, u.password, r.role_name
FROM
users u Left JOIN rules r
ON
u.id = r.user_id
UNION
SELECT
u.id, u.name, u.password, r.role_name
FROM
users u RIGHT JOIN rules r
ON
u.id = r.user_id;