一、DDL(数据定义语言)
1. 作用:
用来定义数据库对象(数据库、表、字段)
2. 数据库操作
① 查询所有数据库
sql
SHOW DATABASES;
② 查询当前数据库:
sql
SELECT DATABASE();
③ 创建数据库:
sql
CREATE DATABASE [ IF NOT EXISTS ] 数据库名 [ DEFAULT CHARSET 字符集] [COLLATE 排序规则 ];
④ 删除数据库:
sql
DROP DATABASE [ IF EXISTS ] 数据库名;
⑤ 使用数据库:
sql
USE 数据库名;
注意:UTF8字符集长度为3字节,有些符号占4字节,所以推荐用utf8mb4字符集
3. 表操作
(1) 查询当前数据库所有表:
sql
SHOW TABLES;
(2) 查询表结构:
sql
DESC 表名;
(3) 查询指定表的建表语句:
sql
SHOW CREATE TABLE 表名;
(4) 创建表:
sql
CREATE TABLE 表名(
字段1 字段1类型 [COMMENT 字段1注释],
字段2 字段2类型 [COMMENT 字段2注释],
字段3 字段3类型 [COMMENT 字段3注释],
...
字段n 字段n类型 [COMMENT 字段n注释]
)[ COMMENT 表注释 ];
注意:最后一个字段后面没有逗号
(5) 添加字段:
sql
ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释] [约束];
例:ALTER TABLE emp ADD nickname varchar(20) COMMENT '昵称';
(6) 修改数据类型:
sql
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
(7) 修改字段名和字段类型:
sql
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
例:将emp表的nickname字段修改为username,类型为varchar(30)
ALTER TABLE emp CHANGE nickname username varchar(30) COMMENT '昵称';
(8) 删除字段:
sql
ALTER TABLE 表名 DROP 字段名;
(9) 修改表名:
sql
ALTER TABLE 表名 RENAME TO 新表名
(10) 删除表:
sql
DROP TABLE [IF EXISTS] 表名;
4. 数据类型
(1) 数值类型
用于存储数字,分整数、浮点、定点数:
① 整数类型(按范围从小到大)
| 类型 | 大小 | 有符号范围 | 无符号范围 | 说明 |
|---|---|---|---|---|
| TINYINT | 1byte | (-128, 127) | (0, 255) | 小整数 |
| SMALLINT | 2bytes | (-32768, 32767) | (0, 65535) | 中整数 |
| MEDIUMINT | 3bytes | (-8388608, 8388607) | (0, 16777215) | 大整数 |
| INT/INTEGER | 4bytes | (-2147483648, 2147483647) | (0, 4294967295) | 常用大整数 |
| BIGINT | 8bytes | (-2^63, 2^63-1) | (0, 2^64-1) | 极大整数 |
✅ 备注:无符号整数写法(如无符号 int):INT UNSIGNED
② 浮点 / 定点数
| 类型 | 大小 | 说明 |
|---|---|---|
| FLOAT | 4bytes | 单精度浮点(范围约 ±3.4E+38) |
| DOUBLE | 8bytes | 双精度浮点(范围约 ±1.8E+308) |
| DECIMAL | 依赖 M/D | 精确定点数(适合金额等场景) |
✅ 备注:double 可指定 "总长 + 小数位",格式:double(总长, 小数位)(如double(4,1))
(2) 字符类型
用于存储字符串 / 二进制数据,分定长、变长、二进制、文本:
| 类型 | 大小范围 | 描述 |
|---|---|---|
| CHAR | 0-255bytes | 定长字符串(性能高) |
| VARCHAR | 0-65535bytes | 变长字符串(性能略低) |
| TINYBLOB | 0-255bytes | 小二进制数据(≤255 字符) |
| TINYTEXT | 0-255bytes | 短文本字符串 |
| BLOB | 0-65535bytes | 长二进制数据 |
| TEXT | 0-65535bytes | 长文本数据 |
| MEDIUMBLOB | 0-16777215bytes | 中等长二进制数据 |
| MEDIUMTEXT | 0-16777215bytes | 中等长文本数据 |
| LONGBLOB | 0-4294967295bytes | 极大二进制数据 |
| LONGTEXT | 0-4294967295bytes | 极大文本数据 |
✅ 性能提示:同长度下,char(n)(如char(10))性能优于varchar(n)(定长存储更高效)
(3) 日期时间类型
用于存储日期、时间相关数据:
| 类型 | 大小 | 范围 | 格式 | 描述 |
|---|---|---|---|---|
| DATE | 3bytes | 1000-01-01 ~ 9999-12-31 | YYYY-MM-DD | 纯日期值 |
| TIME | 3bytes | -838:59:59 ~ 838:59:59 | HH:MM:SS | 时间间隔 / 持续时间 |
| YEAR | 1byte | 1901 ~ 2155 | YYYY | 纯年份值 |
| DATETIME | 8bytes | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期 + 时间 |
| TIMESTAMP | 4bytes | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 带时间戳特性的日期时间 |
二、DML(数据操作语言)
1. 添加数据
(1) 指定字段:
sql
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
(2) 全部字段:
sql
INSERT INTO 表名 VALUES (值1, 值2, ...);
(3) 批量添加数据:
sql
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
注意:
- 字符串和日期类型数据应该包含在引号中
- 插入的数据大小应该在字段的规定范围内
2. 更新和删除数据
(1) 修改数据:
sql
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ... [ WHERE 条件 ];
例:
UPDATE emp SET name = 'Jack' WHERE id = 1;
(2) 删除数据:
java
DELETE FROM 表名 [ WHERE 条件 ];
三、DQL(数据查询语言)
1. 语法:
sql
SELECT
字段列表
FROM
表名字段
WHERE
条件列表
GROUP BY
分组字段列表
HAVING
分组后的条件列表
ORDER BY
排序字段列表
LIMIT
分页参数
2. 基础查询
(1) 查询多个字段:
sql
SELECT 字段1, 字段2, 字段3, ... FROM 表名;
SELECT * FROM 表名;
(2) 设置别名:
sql
SELECT 字段1 [ AS 别名1 ], 字段2 [ AS 别名2 ], 字段3 [ AS 别名3 ], ... FROM 表名;
SELECT 字段1 [ 别名1 ], 字段2 [ 别名2 ], 字段3 [ 别名3 ], ... FROM 表名;
(3) 去除重复记录:
sql
SELECT DISTINCT 字段列表 FROM 表名;
3. 条件查询
(1) 语法:
sql
SELECT 字段列表 FROM 表名 WHERE 条件列表;
(2) 条件:
| 比较运算符 | 功能 |
|---|---|
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| = | 等于 |
| <> 或 != | 不等于 |
| BETWEEN ... AND ... | 在某个范围内(含最小、最大值) |
| IN(...) | 在in之后的列表中的值,多选一 |
| LIKE 占位符 | 模糊匹配(_匹配单个字符,%匹配任意个字符) |
| IS NULL | 是NULL |
| 逻辑运算符 | 功能 |
|---|---|
| AND 或 && | 并且(多个条件同时成立) |
| OR 或 || | 或者(多个条件任意一个成立) |
| NOT 或 ! | 非,不是 |
(3) 例子:
sql
-- 1. 查询年龄等于 88 的员工
select * from emp where age = 88;
-- 2. 查询年龄小于 20 的员工
select * from emp where age < 20;
-- 3. 查询没有身份证号的员工信息
select * from emp where idCard is null;
-- 4. 查询所有身份证号的员工信息
select * from emp where idCard is not null;
-- 5. 查询年龄不等于 88 的员工信息
select * from emp where age != 88;
-- 6. 查询年龄在15岁(包含)到20岁(包含)之间的员工信息
select * from emp where age >= 15 and age <= 20;
select * from emp where age between 15 and 20;
-- 7. 查询性别为 女 且年龄小于 25 岁的员工信息
select * from emp where gender = '女' and age < 25
-- 8. 查询年龄等于 18 或 20 或 40 的员工信息
select * from emp where age in(18,20,40);
-- 9. 查询姓名为两个字的员工信息
select * from emp where name like '__';
-- 10. 查询身份证号最后一位是X的员工信息
select * from emp where idCard like '%X';
注意:MySQL 中查询 idCard 为 NULL 的员工时,不能用 idCard = null 或 idCard == null,在 MySQL 中,NULL表示「未知值」,不是一个具体的数值 / 字符串,因此普通的比较运算符(=、==、!=、<>)无法和 NULL 进行有效比较 ------ 用这些运算符和 NULL 比较的结果既不是TRUE也不是FALSE,而是NULL(不成立),最终查不到任何数据。
4. 聚合查询(聚合函数)
(1) 常见聚合函数:
| 函数 | 功能 |
|---|---|
| count | 统计数量 |
| max | 最大值 |
| min | 最小值 |
| avg | 平均值 |
| sum | 求和 |
(2) 语法:
sql
SELECT 聚合函数(字段列表) FROM 表名;
(3) 代码示例:
sql
-- 1.统计该企业员工数量
select count(*) from emp;
select count(id) from emp;
-- 2.统计该企业员工的平均年龄
select avg(age) from emp;
-- 3.统计该企业员工的最大年龄
select max(age) from emp;
-- 4.统计西安地区员工的年龄之和
select sum(age) from emp where workaddress = '西安';
注意:null 值不参与所有聚合函数运算
5. 分组查询
(1) 语法:
sql
SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后的过滤条件 ];
(2) where 和 having 的区别:
- 执行时机不同:where是分组之前进行过滤,不满足where条件不参与分组;having是分组后对结果进行过滤。
- 判断条件不同:where不能对聚合函数进行判断,而having可以。
(3) 代码示例:
sql
-- 1.根据性别分组,统计男性员工和女性员工的数量
select gender,count(*) from emp group by gender;
-- 2.根据性别分组,统计男性员工和女性员工的平均年龄
select gender,avg(age) from emp group by gender;
-- 3.查询年龄小于45的员工,并根据工作地址分组,获取员工数量大于等于3的工作地址
select workaddress,count(*) from emp where age < 45 group by workaddress having count(*) >= 3;
关键逻辑:
① HAVING COUNT(*) >= 3
分组后的筛选:只保留 "统计人数≥3" 的分组 ------ 比如西安分组只有 2 人,就会被筛掉;北京有 6 人、上海 4 人、江苏 3 人,都会保留。
→ 记住:HAVING只管 "分组后的统计结果"(比如 COUNT (*)),不管 "单个员工的字段"。
② SELECT workaddress,count(*)
最终展示:把筛选后的分组结果展示出来,列是 "工作地址" 和 "对应人数"。
(4) 注意事项
- 执行顺序:where > 聚合函数 > having
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
6. 排序查询
(1) 语法:
sql
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
(2) 排序方式:
- ASC: 升序(默认)
- DESC: 降序
(3) 代码示例:
sql
-- 1.根据年龄对公司的员工进行升序排序
select * from emp order by age asc;
select * from emp order by age;
-- 2.根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
select * from emp order by age asc, entrydate desc;
(4) 注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
7. 分页查询
(1) 语法:
sql
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;
(2) 注意:
- 起始索引从0开始,起始索引 = (查询页码 - 1) * 每页显示记录数
- 分页查询是数据库的方言,不同数据库有不同实现,MySQL是LIMIT
- 如果查询的是第一页数据,起始索引可以省略,直接简写 LIMIT 10
(3) 代码示例:
sql
-- 1.查询第1页员工数据,每页展示10条记录
select * from emp limit 0,10;
select * from emp limit 10;
-- 2.查询第2条
select * from emp limit 10,10;
8. 综合练习
sql
-- 1.查询年龄为20,21,22,23岁的女性员工信息
select * from emp where gender = '女' and age in (20,21,22,23);
-- 2.统计员工表中,年龄小于60岁的,男性员工和女性员工的人数
select gender, count(*) from emp where age < 60 group by gender
-- 3.查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序
select name,age from emp where age <= 35 order by age asc, entrydate desc;
-- 4.查询性别为男,且年龄在20-40岁(含)以内的前5个员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序时间
select * from emp where gender = '男' and age between 20 and 40 order by age asc, entrydate desc limit 5;
9. DQL 编写顺序
sql
1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. ORDER BY → 6. LIMIT
10. DQL执行顺序
FROM -> WHERE -> GROUP BY、HAVING -> SELECT -> ORDER BY -> LIMIT
四、DCL
1. 管理用户
(1) 查询用户:
sql
USE mysql;
SELECT * FROM user;
(2) 创建用户:
sql
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
(3) 修改用户密码:
sql
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';
(4) 删除用户:
sql
DROP USER '用户名'@'主机名';
(5) 代码示例:
sql
-- 创建用户test,只能在当前主机localhost访问
create user 'test'@'localhost' identified by '123456';
-- 创建用户test,能在任意主机访问
create user 'test'@'%' identified by '123456';
create user 'test' identified by '123456';
-- 修改密码
alter user 'test'@'localhost' identified with mysql_native_password by '1234';
-- 删除用户
drop user 'test'@'localhost';
2. 权限控制
(1) 常用权限:
| 权限 | 说明 |
|---|---|
| ALL, ALL PRIVILEGES | 所有权限 |
| SELECT | 查询数据 |
| INSERT | 插入数据 |
| UPDATE | 修改数据 |
| DELETE | 删除数据 |
| ALTER | 修改表 |
| DROP | 删除数据库/表/视图 |
| CREATE | 创建数据库/表 |
(2) 查询权限:
sql
SHOW GRANTS FOR '用户名'@'主机名';
(3) 授予权限:
sql
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
(4) 撤销权限:
sql
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
(5) 注意事项
- 多个权限用逗号分隔
- 授权时,数据库名和表名可以用 * 进行通配,代表所有
五、 实用技巧
1. DataGrip 快速执行单行 SQL 的方法
使用 Ctrl+Enter (Windows/Linux),无需选中整行 ,只需将光标定位在目标行,按下此快捷键,DataGrip 会自动执行该行完整 SQL 语句。
2. 换行技巧(无需移到行尾)
Windows/Linux:Shift + Enter
3. 单行注释(最常用)
用 --(两个减号)开头,后面跟注释内容,注释范围从--到行尾。
sql
-- 这是单行注释(整行注释)
SELECT * FROM employee; -- 这是行尾注释(注释该行后面的内容)
-- INSERT INTO employee (id, name) VALUES (2, '李四'); -- 注释掉整行执行语句