第一部分:数据库基础
1.1 什么是数据库
⭐ 老师强调 :数据库是长期存储在计算机内的、有组织的、可共享的数据集合 ,本质上是一个文件系统。和Excel不同,Excel随便塞数据没格式约束,而数据库必须按提前设好的特定格式存数据。
数据库 vs Excel:
| 对比 | Excel | 数据库 |
|---|---|---|
| 数据约束 | 无格式限制 | 必须符合预设表结构 |
| 数据量 | 适合小数据 | 支持海量数据 |
| 并发访问 | 弱 | 强 |
| 数据规范 | 不严格 | 严格 |
1.2 数据库分类
| 类型 | 说明 | 代表产品 | 是否支持SQL |
|---|---|---|---|
| 关系型数据库 | 用二维表存储数据 | MySQL、SQL Server、DB2、Oracle | ✅ 支持 |
| 非关系型数据库(NoSQL) | 非二维表存储(键值对、文档等) | Redis、MongoDB | ❌ 不支持 |
⭐ 老师强调 :关系型数据库都支持SQL语言操作;非关系型数据库暂时不支持SQL。两者适用场景不同,复杂项目常需搭配使用。
1.3 SQL语言概述
⭐ 老师强调 :SQL(Structured Query Language,结构化查询语言)是程序与数据库沟通的唯一语言,所有关系型数据库都能用SQL操作,各库仅有细微差别。
SQL语言分类:
| 分类 | 全称 | 操作对象 | 常用关键字 |
|---|---|---|---|
| DDL | 数据定义语言 | 数据库、表结构 | CREATE、ALTER、DROP、SHOW、USE |
| DML | 数据操作语言 | 表中数据 | INSERT、UPDATE、DELETE |
| DQL | 数据查询语言 | 表中数据(查询) | SELECT |
| DCL | 数据控制语言 | 用户权限 | CREATE USER、GRANT、REVOKE |
| TCL | 事务控制语言 | 事务 | BEGIN、COMMIT、ROLLBACK |
第二部分:MySQL数据类型
2.1 数值类型
| 类型 | 字节数 | 取值范围 | 用途 |
|---|---|---|---|
tinyint |
1 | -128 ~ 127 | 状态值(0/1/2)、性别开关 |
smallint |
2 | -32768 ~ 32767 | 较小整数 |
mediumint |
3 | -8388608 ~ 8388607 | 中等整数 |
int |
4 | -21亿 ~ 21亿 | 最常用整数 |
bigint |
8 | 超大范围 | 订单号、大数据量主键 |
float |
4 | 单精度小数 | 有精度丢失 |
double |
8 | 双精度小数 | 有精度丢失 |
decimal |
动态 | 精确小数 | 金额、价格(无精度丢失) |
类型选择要点:
-- 状态值 → tinyint(省空间)
sex TINYINT DEFAULT 0 -- 0男 1女
-- 普通整数 → int
age INT
-- 订单号 → bigint
order_id BIGINT
-- 金额 → decimal(避免精度丢失)
price DECIMAL(10,2) -- 总长度10位,小数2位
⭐ 老师强调 :int最大值达不到11位,手机号不能用int存 。涉及金钱、价格等金额字段,不要用float/double,必须用decimal,避免精度丢失。手机号可能含区号且首位为0,建议用字符串存。
2.2 字符串类型
| 类型 | 特点 | 最大长度 | 适用场景 |
|---|---|---|---|
char |
固定长度,不足补空格 | 255 | 手机号(11位)、身份证号、验证码 |
varchar |
可变长度,存实际字符 | 65535 | 姓名、地址、标题(长度不一) |
text |
可变大文本,无长度限制 | 无限制 | 文章内容、富文本内容 |
-- 固定长度 → char
phone CHAR(11)
-- 长度不一但有限 → varchar
name VARCHAR(50)
title VARCHAR(255) -- 习惯设255
-- 内容不可预知 → text
content TEXT
⭐ 老师强调 :char 像定长格子,不管放没放满都占那么大地方。varchar 只存实际数据,但超255后每存一个值需多占2字节。text来多少存多少,专治"无限长"内容。
2.3 日期时间类型
| 类型 | 格式 | 说明 |
|---|---|---|
date |
yyyy-MM-dd | 仅日期(年月日) |
time |
HH:mm:ss | 仅时间(时分秒) |
datetime |
yyyy-MM-dd HH:mm:ss | 日期+时间 |
year |
yyyy | 仅年份 |
birth_date DATE
created_at DATETIME
⭐ 老师强调 :date 只存年月日,datetime包含时分秒,选哪个看是否需要精确到秒。
第三部分:数据库约束
3.1 约束概述
⭐ 老师强调 :约束是为了确保数据的准确性与完整性,限制数据存取规则,不是什么数据都能随便写。
3.2 常用约束
| 约束类型 | 说明 | 作用范围 |
|---|---|---|
| 主键约束 | 非空+唯一,标识整行 | 列级/表级 |
| 自增约束 | 数值自动+1 | 列级 |
| 非空约束 | 字段必须有值 | 列级 |
| 默认值约束 | 插入不填时自动填充 | 列级 |
| 唯一约束 | 字段值不能重复(可为空) | 列级/表级 |
| 外键约束 | 引用其他表主键 | 表级 |
⭐ 老师强调 :主键一张表只能有一个,但可由多个字段组成(联合主键)。主键默认非空且唯一,设主键后不必重复写NOT NULL。主键之外其他字段都可重复,只要主键不同就是不同数据。
3.3 列级约束 vs 表级约束
| 约束类型 | 作用范围 | 示例 |
|---|---|---|
| 列级约束 | 针对当前单列 | NOT NULL、DEFAULT、UNIQUE、PRIMARY KEY |
| 表级约束 | 针对整张表 | 联合主键、多字段唯一约束、外键约束 |
CREATE TABLE demo (
-- 列级约束
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
name VARCHAR(20) NOT NULL COMMENT '姓名',
age INT DEFAULT 18 COMMENT '年龄',
-- 表级约束(写在最后)
FOREIGN KEY (cid) REFERENCES class(id)
);
3.4 外键约束
⭐ 老师强调 :外键是字段值取自另一表主键的字段,如student表的cid对应class表的id。但实际开发中很少设库级外键 ,因为删除、添加限制麻烦。改用业务代码控制:添加前查class表,非1、2禁止写入。
第四部分:DDL --- 数据定义语言
4.1 数据库操作
-- 创建数据库(若不存在)
CREATE DATABASE IF NOT EXISTS test DEFAULT CHARSET utf8mb4;
-- 查看所有数据库
SHOW DATABASES;
-- 切换数据库
USE qcby07;
-- 删除数据库(⚠️慎用)
DROP DATABASE IF EXISTS test;
⭐ 老师强调 :不建议用DROP删库,可能直接删掉系统文件,新手易误删。
4.2 表操作
-- 建表语法
CREATE TABLE 表名(
字段名 数据类型 列级完整性约束条件,
字段名 数据类型 列级完整性约束条件,
表级约束条件
);
-- 建表示例
CREATE TABLE demo(
id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT 'demoid',
name VARCHAR(20) NOT NULL COMMENT 'demo姓名',
age INT(11) DEFAULT 18 COMMENT '年龄'
);
-- 查看表结构
DESC demo;
-- 修改表结构(添加字段)
ALTER TABLE demo ADD sex VARCHAR(20);
-- 修改表结构(修改字段类型)
ALTER TABLE demo MODIFY sex INT(5);
-- 修改表结构(删除字段)
ALTER TABLE demo DROP sex;
-- 删除表(若存在)
DROP TABLE IF EXISTS demo;
4.3 ALTER语句的四种操作
| 操作 | 关键字 | 说明 |
|---|---|---|
| 添加字段 | ADD |
新增字段 |
| 修改字段类型 | MODIFY |
改字段类型 |
| 修改字段名 | CHANGE |
改名+类型 |
| 删除字段 | DROP |
删除字段 |
4.4 反引号的使用
⭐ 老师强调:表名或字段名若与SQL关键字重名,直接写会报错。用键盘左上角的**反引号(`)**做转义,撞名也能正常执行。
-- 如果表名叫select,必须加反引号
SELECT * FROM `select`;
第五部分:DML --- 数据操作语言
5.1 插入数据(INSERT)
-- 基本插入(id自动递增)
INSERT INTO student(name, age, sex) VALUES ('梨花', 25, '女');
-- 插入多条
INSERT INTO student(name, age) VALUES ('张三', 20), ('李四', 21);
5.2 修改数据(UPDATE)
-- ⚠️ 必须加WHERE条件
UPDATE student SET name='lili12', age=30 WHERE id=4;
⭐ 老师强调 :UPDATE必须加WHERE条件,否则整张表所有记录都会被修改!
5.3 删除数据(DELETE)
-- ⚠️ 必须加WHERE条件
DELETE FROM student WHERE id=7;
⭐ 老师强调 :DELETE必须加WHERE条件,否则整张表数据全部删除!
第六部分:DQL --- 数据查询语言(核心)
6.1 基础查询
-- 查询全部字段(*)
SELECT * FROM student;
-- 查询指定字段(多字段用逗号隔开)
SELECT id, name, age, sex FROM student;
-- 去重查询
SELECT DISTINCT age FROM student;
-- 别名:AS可省略
SELECT age AS 年龄 FROM student;
SELECT age 年龄 FROM student; -- 省略AS
⭐ 老师强调 :查询是行级遍历,每行取字段值。
*代表全字段,多个字段用逗号而非空格分隔。AS可省略,用空格隔开即可。
6.2 WHERE条件筛选
比较运算符:
-- 大于 小于 等于
SELECT * FROM student WHERE age > 20;
SELECT * FROM student WHERE age >= 18;
SELECT * FROM student WHERE age = 24;
-- 不等于(两种写法)
SELECT * FROM student WHERE age != 24;
SELECT * FROM student WHERE age <> 24; -- 等价
IN 与 BETWEEN:
-- IN:值在指定集合中
SELECT * FROM student WHERE age IN (18, 31, 28);
-- BETWEEN AND:闭区间(含两端)
SELECT * FROM student WHERE age BETWEEN 18 AND 28;
-- 开区间(不含18和28)
SELECT * FROM student WHERE age > 18 AND age < 28;
逻辑运算符:
-- AND:必须同时满足
SELECT * FROM student WHERE age > 18 AND age <= 28 AND name = '李四';
-- OR:满足任一即可
SELECT * FROM student WHERE age > 30 OR name = '李四';
-- NOT IN:不在集合中
SELECT * FROM student WHERE age NOT IN (18, 31, 28);
-- IS NULL / IS NOT NULL:判空
SELECT * FROM student WHERE age IS NOT NULL;
模糊查找(LIKE):
-- _:恰好一位字符
SELECT * FROM student WHERE name LIKE '_a_'; -- 名字为3位,中间是a
-- %:任意位字符(含0位)
SELECT * FROM student WHERE name LIKE '%a%'; -- 包含a即可
SELECT * FROM student WHERE name LIKE 'a%'; -- 以a开头
SELECT * FROM student WHERE name LIKE '%a'; -- 以a结尾
⭐ 老师强调 :LIKE不加占位符时和等号没区别。
%可匹配任意长度,_只占一位不能空。
6.3 ORDER BY --- 排序
-- 升序(ASC可省略,默认)
SELECT * FROM student ORDER BY age ASC;
SELECT * FROM student ORDER BY age; -- 默认升序
-- 降序
SELECT * FROM student ORDER BY age DESC;
-- 按日期倒序(最新在前)
SELECT * FROM student ORDER BY birth DESC;
⭐ 老师强调 :
ASC表示升序,可省略;DESC表示降序,不能省。文本字段排序受字符编码影响。
6.4 LIMIT --- 分页查询
-- 语法1:LIMIT 起始索引, 查询条数
SELECT * FROM student LIMIT 0, 2; -- 第1页(索引从0开始)
SELECT * FROM student LIMIT 2, 2; -- 第2页
SELECT * FROM student LIMIT 4, 2; -- 第3页
-- 语法2:LIMIT 条数 OFFSET 起始索引
SELECT * FROM student LIMIT 2 OFFSET 0; -- 等价于 LIMIT 0,2
分页公式:
-- pageSize = 每页条数 page = 当前页码
SELECT * FROM student LIMIT (page - 1) * pageSize, pageSize;
⭐ 老师强调 :索引和id没关系,是对WHERE筛选后的结果从0开始编号 。
WHERE、ORDER BY、LIMIT同时用时,顺序固定:WHERE → ORDER BY → LIMIT,LIMIT永远放最后。
6.5 聚合函数
⭐ 老师强调:聚合函数是"一堆数据出一个结果"------把多行数据聚合成单个值。
| 函数 | 说明 |
|---|---|
MAX() |
求最大值 |
MIN() |
求最小值 |
AVG() |
求平均值 |
SUM() |
求和 |
COUNT() |
统计数量(不统计为NULL的记录) |
-- 普通查询:返回所有年龄
SELECT age FROM student;
-- 聚合查询:返回一个值
SELECT MAX(age) FROM student;
SELECT MIN(age) FROM student;
SELECT AVG(age) FROM student;
SELECT SUM(age) FROM student;
-- COUNT区别
SELECT COUNT(*) FROM student; -- 统计所有行数
SELECT COUNT(age) FROM student; -- 不统计age为空的记录
6.6 GROUP BY --- 分组
-- 按班级分组,求每班最大年龄
SELECT MAX(age), cid FROM student GROUP BY cid;
-- 分组前筛选(WHERE)
SELECT MAX(age), cid FROM student WHERE sex = '男' GROUP BY cid;
⭐ 老师强调 :GROUP BY是"先分堆、后统计"。分组前用
WHERE过滤原表数据,分组后用HAVING过滤分组后的结果。
6.7 HAVING --- 分组后筛选
-- 分组后只留班级id=2的数据
SELECT MAX(age), cid FROM student WHERE sex = '男' GROUP BY cid HAVING cid = 2;
WHERE vs HAVING:
| 对比 | WHERE | HAVING |
|---|---|---|
| 执行时机 | 分组前 | 分组后 |
| 作用对象 | 原表记录 | 分组后的结果 |
| 能否用聚合函数 | ❌ 不能 | ✅ 能 |
6.8 完整查询顺序
SELECT 字段
FROM 表名
WHERE 条件 -- 1. 过滤行
GROUP BY 分组字段 -- 2. 分组
HAVING 条件 -- 3. 过滤分组
ORDER BY 排序字段 -- 4. 排序
LIMIT 起始, 数量; -- 5. 分页
⭐ 老师强调:执行顺序为 WHERE → GROUP BY → HAVING → ORDER BY → LIMIT,各子句顺序不能乱。
附录一:完整SQL示例(ok.sql)
-- 查找
SELECT id,name,age,sex FROM student;
SELECT * FROM student;
-- 添加
INSERT INTO student(name,age,sex) VALUES('梨花',25,'女');
-- 修改
UPDATE student SET name='lili12', age=30 WHERE id=4;
-- 删除
DELETE FROM student WHERE id=7;
-- 查数量
SELECT COUNT(*) FROM student;
-- 基础查询
SELECT * FROM student WHERE name='梨花' AND sex='男';
-- 去重
SELECT DISTINCT age FROM student;
-- 别名
SELECT age FROM student s1;
-- 比较运算符
SELECT * FROM student WHERE age <> 24;
-- IN / BETWEEN
SELECT * FROM student WHERE age IN(18,31,28);
SELECT * FROM student WHERE age BETWEEN 18 AND 28;
-- 逻辑运算符
SELECT * FROM student WHERE age>18 AND age<=28 AND name='李四';
SELECT * FROM student WHERE age>30 OR name='李四';
-- NOT IN / IS NOT NULL
SELECT * FROM student WHERE age NOT IN(18,31,28);
SELECT * FROM student WHERE age IS NOT NULL;
-- 模糊查找
SELECT * FROM student WHERE name LIKE '%a%';
-- 分页查询
SELECT * FROM student LIMIT 0,2;
-- 排序
SELECT * FROM student ORDER BY birth DESC;
-- 组合查询
SELECT * FROM student WHERE sex='男' ORDER BY birth DESC LIMIT 0,2;
-- 聚合函数
SELECT MAX(age) FROM student;
SELECT COUNT(*) FROM student;
SELECT COUNT(age) FROM student;
-- 分组
SELECT MAX(age), cid FROM student GROUP BY cid;
-- WHERE + GROUP BY + HAVING + LIMIT
SELECT MAX(age), cid FROM student WHERE sex='男' GROUP BY cid HAVING cid=2 LIMIT 0,1;