mysql 基础

在数据库领域,DDL、DML 和 DQL 是结构化查询语言(SQL)的三个核心组成部分,它们各自负责不同的数据库操作。

简单来说,它们分别扮演着"建筑师"、"管理员"和"分析师"的角色。

🏗️ DDL (数据定义语言)

DDL (Data Definition Language) 负责定义和管理数据库的结构,例如创建、修改或删除数据库、数据表、索引等对象。它不操作表中的具体数据,而是操作存放数据的"容器"。

  • 核心作用:定义或修改数据库对象的"骨架"。
  • 常用命令
    • CREATE:创建数据库或表。
    • ALTER:修改表结构,如添加或删除字段。
    • DROP:删除数据库或表。
    • TRUNCATE:清空表中的所有数据,但保留表结构。
  • 特点 :DDL 语句执行后通常会立即生效并自动提交,操作不可回滚

✏️ DML (数据操纵语言)

DML (Data Manipulation Language) 负责对数据库表中的数据进行增、删、改等操作。它操作的是"容器"里的具体内容。

  • 核心作用:对表中的具体记录进行增删改。
  • 常用命令
    • INSERT:向表中插入新数据。
    • UPDATE:修改表中已有的数据。
    • DELETE:从表中删除数据。
  • 特点 :DML 操作通常在一个事务中进行,可以提交(COMMIT)使更改永久生效,也可以回滚(ROLLBACK)来撤销更改。

🔍 DQL (数据查询语言)

DQL (Data Query Language) 专门用于从数据库中查询和检索数据。它是日常工作中使用频率最高的一类语句。

  • 核心作用:从数据库中读取数据,不做任何修改。
  • 核心命令
    • SELECT:这是 DQL 中唯一的核心命令,配合 FROMWHEREGROUP BYORDER BY 等子句,可以实现各种复杂的查询。
  • 特点:只读不写,不会对数据库中的数据和结构造成任何改变。

📌 核心区别速览

为了更清晰地理解,可以参考下表:

分类 全称 核心作用 常用命令
DDL 数据定义语言 定义/修改数据库结构 CREATE, ALTER, DROP
DML 数据操纵语言 增/删/改表中的数据 INSERT, UPDATE, DELETE
DQL 数据查询语言 查询表中的数据 SELECT
💡 补充说明

关于 SELECT 命令的归属,存在不同观点。一些资料将其归为 DML 的一部分,因为它也操作数据(读取)。但在现代数据库教学和实践中,为了强调其"只读"的特性并与增删改操作区分开,更普遍的做法是将其单独划分为 DQL。

显示库

bash 复制代码
show databases; --显示库
use mysql; --选择库
show tables; 显示表
desc user; 显示表结构
select * from user; // 查询表

常见数据库表

sql 复制代码
## 创建数据库表
CREATE TABLE t_student(
sno int(6), -- 6显示长度
sname varchar(5), -- 5个字符
sex char(1),
age INT(3),
enterdate DATE,
classname varchar(16),
email varchar(15)
);

-- 查看表的结构
desc t_student;

-- 查看表中的数据
select * from t_student; 

-- 查看建表语句
show create table t_student;

添加数据

sql 复制代码
-- 查看表记录
select * from t_student;

-- 在t_student 中插入数据
insert into t_student values (1,'张三','男',18,'2026-4-1','安全1班','158@163.com');
insert into t_student values (1234567,'张三','男',18,'2026-4-1','安全1班','158@163.com');
insert into t_student values (2,'张三','男',18,'2026.5.1','安全1班','158@163.com');
insert into t_student values (5,'张三','男',18,now(),'安全1班','158@163.com');
insert into t_student (sno,sname,enterdate) values (6,'李四','2026-5-8');

修改删除数据

sql 复制代码
-- 修改数据
update t_student set sex = '女';
update t_student set sex = '男' where sno = 2;
UPDATE t_student SET age = 21 where sno = 6;

-- 删除数据
delete from t_student where sno = 5;

DDL 和 DML的补充

sql 复制代码
-- 创建一张表,快速添加,数据和结构都和t_student 一样
create table t_student2
as 
select * from t_student;

select * from t_student2;


-- 创建一张表,快速添加,结构一样,数据没有
create table t_student3
as 
select * from t_student where 1=2;

select * from t_student3;

-- 创建一张表,快速添加,部分数据和结构都和 
create table t_student4
as 
select sno,sname,age from t_student where sno = 2;

select * from t_student4;

-- 删除和清空数据
delete from t_student; -- 只是删除数据,没有重新建表
truncate TABLE t_student; -- 保留表结构,删除所有数据,重新建表

DQL

最简单的SQL语句

sql 复制代码
-- 对emp 表查询
select * FROM emp; -- * 代表所有数据

-- 显示部分列
select empno, ename, sal from emp;
-- 显示部分行
select * from emp where sal > 2000;
-- 显示部分行和部分列
select empno, ename, sal from emp WHERE sal > 2000;

-- 起别名
select empno 员工编号, ename 姓名, sal 工资 from emp;
-- 运算符
select empno, ename, sal, sal+1000 as '涨薪后', deptno from emp where sal < 2500;
select empno,ename,sal,comm,sal+comm from emp;

-- 去重操作
select job FROM emp;
select DISTINCT job from emp;
select distinct job,deptno from emp; -- 对后面的所有列组合去重,而不是单独的某一列去重

-- 排序
select * from emp order by sal; -- 默认升序
select * from emp order by sal asc; -- asc 升序
select * from emp order by sal desc; -- desc 降序
select * from emp order by sal asc, deptno desc; -- 组合排序

where 子句

sql 复制代码
-- 查看emp
select * from emp;

-- 
select * from emp WHERE deptno = 10;
select * from emp WHERE deptno => 10;
select * from emp WHERE deptno != 10;
select * from emp where job = 'CLERK';
select * from emp where job = 'clerk'; -- 默认情况下不区分大小写
select * from emp where binary job = 'clerk'; -- binary 区分大小写
select * from emp where hiredate < '1981-12-25' ORDER BY hiredate;

-- and 
select * from emp where sal > 1500 and sal < 3000;
select * from emp where sal > 1500 && sal < 3000;
select * from emp where sal > 1500 and sal < 3000 order by sal;
select * from emp where sal BETWEEN 1500 and 3000;

-- OR
SELECT * FROM emp WHERE deptno = 10 OR deptno = 20;
SELECT * FROM emp WHERE deptno IN (10,30);

-- 模糊查询 % 代表任意多个字符 
SELECT * FROM emp WHERE ename LIKE '%A%';
-- _代表一个字符
SELECT * FROM emp WHERE ename LIKE '___A%';

-- null 判断
SELECT * FROM emp WHERE comm is NULL;
SELECT * FROM emp WHERE comm is NOT NULL;

-- 小括号的使用
SELECT * FROM emp WHERE job = 'SALESMAN' or job = 'clerk' and sal >= 1500;
SELECT * FROM emp WHERE (job = 'SALESMAN' or job = 'clerk') and sal >= 1500;

函数的分类

sql 复制代码
- 函数举例:
select empno,ename,lower(ename),upper(ename),sal from emp;
-- 函数的功能:封装了特定的一些功能,我们直接拿过来使用,可以实现对应的功能
-- 函数作用:为了提高select的能力
-- 注意:函数没有改变数据自身的值,而是在真实数据的上面进行加工处理,展示新的结果而已。
select max(sal),min(sal),count(sal),sum(sal),avg(sal) from emp;
-- 函数的分类:
-- lower(ename),upper(ename) :改变每一条结果,每一条数据对应一条结果  -- 单行函数
-- max(sal),min(sal),count(sal),sum(sal),avg(sal):多条数据,最终展示一个结果  -- 多行函数

单行函数

sql 复制代码
-- 单行函数包含:
-- 1.字符串函数
select ename,length(ename),substring(ename,2,3) from emp;
-- substring字符串截取,2:从字符下标为2开始,3:截取长度3    (下标从1开始)
-- 2.数值函数
select abs(-5),ceil(5.3),floor(5.9),round(3.14) from dual; -- dual实际就是一个伪表 
select abs(-5) 绝对值,ceil(5.3) 向上取整,floor(5.9) 向下取整,round(3.14) 四舍五入;  -- 如果没有where条件的话,from dual可以省略不写
select ceil(sal) from emp;
select 10/3,10%3,mod(10,3) ;
-- 3.日期与时间函数 
select * from emp;
select curdate(),curtime() ; -- curdate()年月日 curtime()时分秒
select now(),sysdate(),sleep(3),now(),sysdate() from dual; -- now(),sysdate() 年月日时分秒
insert into emp values (9999,'lili','SALASMAN',7698,now(),1000,null,30);
-- now()可以表示年月日时分秒,但是插入数据的时候还是要参照表的结构的
desc emp;

-- 4 流程函数
-- if相关
select empno,ename,sal,IF(sal >=2500,'高薪','底薪') as '薪资等级' from emp;
select empno,ename,sal,comm,sal+ifnull(comm,0) from emp; -- 如果comm 是null取0,单分支
select NULLIF(1,1), NULLIF(2,1) FROM DUAL; -- 如果v1 == v2,返回null,否则返回v1
-- case 相关
select empno,ename,job,
-- 等值判断
case job
	when 'CLERK' then '店员'
	when 'SALESMAN' then '销售'
	when 'MANAGER' then '经理'
	else '其他'
end as '职位',
sal from emp;

-- 区间判断
select empno,ename,sal,
case
	when sal <= 1000 then 'A'
	when sal <= 2000 then 'B'
	when sal <= 3000 then 'C'
	else 'D'
end as '薪资等级',
deptno from emp; 


-- 6 其他函数
select database(), user(), version() from dual;

-- 多行函数
select max(sal),min(sal),count(sal),sum(sal),avg(sal) from emp;
-- 多行函数会自动忽略null值
select max(comm),min(comm),count(comm),sum(comm),avg(comm) from emp;

-- count 统计记录数 方式1
select * from emp;
select count(ename) from emp;
select count(*) from emp;
-- 方式2
select 1 from emp;
select count(1) from emp;

分组查询group by

sql 复制代码
-- 多行函数
select max(sal),min(sal),count(sal),sum(sal),avg(sal) from emp;
-- 多行函数会自动忽略null值
select max(comm),min(comm),count(comm),sum(comm),avg(comm) from emp;

-- count 统计记录数 方式1
select * from emp;
select count(ename) from emp;
select count(*) from emp;
-- 方式2
select 1 from emp;
select count(1) from emp;

分组

sql 复制代码
-- 统计个部分的平均工资
select deptno, avg(sal) from emp GROUP BY deptno; 
select deptno, avg(sal) from emp GROUP BY deptno ORDER BY avg(sal); 

-- 统计各个岗位的平均工资
select job , avg(sal) from emp group by job;
select job , lower(job), avg(sal) from emp group by job;

having

sql 复制代码
-- 统计个部分的平均工资 只显示2000 以上的
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;
select deptno,avg(sal) as 平均工资 from emp group by deptno having 平均工资 > 2000;
select deptno,avg(sal) as 平均工资 from emp group by deptno having 平均工资 > 2000 order by 平均工资 DESC;

-- 统计各个岗位的平均工资,除了manager
SELECT job , avg(sal) FROM emp where job != 'MANAGER' GROUP BY job;
select job , avg(sal) from emp GROUP BY job having job != 'MANAFER' ORDER BY avg(sal);
-- where是在分组前过滤,having是在分组后过滤

单表查询总结

sql 复制代码
-- 单表查询练习
	-- 1. 列出工资最小值小于2000的职位
	select job , min(sal) from emp GROUP BY job having min(sal) < 2000;

	-- 2 列出平均工资大于1200元的部门和工作搭配组合
	select deptno,job,avg(sal)
	from emp
	group by deptno,job 
	having avg(sal) > 1200
	order by deptno;

	-- 统计人数小于4的部门的平均工资
	select deptno , count(1), avg(sal)
	from emp
	group by deptno 
	having count(sal) < 4;

	-- 统计部分最高工资,排除最高工资小于3000的部分

	select deptno , max(sal)
	from emp
	group by deptno
	having max(sal) < 3000;

多表查询

sql 复制代码
 -- cross join 交叉查询
 select * 
 from emp 
 cross join dept;

 -- 自然链接 natural join 
 -- 优点自动匹配同名的列,同名列只展示一次
 select * 
 from emp
 natural join dept;


 select empno,ename,sal,dname,loc
 from emp
 natural join dept;
 -- 缺点: 查询字段的时候没有指定字段所属的数据库表,效率低

 -- 解决指定表明
select emp.empno,emp.ename,emp.sal,dept.dname,dept.loc
from emp
natural join dept;

-- 表名太长

select e.empno,e.ename,e.sal,d.dname,d.loc
from emp e
natural join dept d;



-- 缺点 natural join 自动匹配所有的同名列,我们希望匹配指定的同名列
-- 内连接 inner 解决 using 子句
select e.empno,e.ename,e.sal,d.dname,d.loc
from emp e
inner join dept d -- inner 可以不写
using(deptno);

-- using 缺点关联的字段必须同名
-- 解决 : 内连接 - on 子句
select * 
from emp e
inner join dept d
on(e.DEPTNO = d.DEPTNO);


select * 
from emp e
inner join dept d
on(e.DEPTNO = d.DEPTNO)
WHERE sal > 3000;

-- 条件:
-- 刷选条件:where HAVING
-- 链接条件:on,using,natural;
-- SQL 99 语法;刷新条件和链接条件是分开的

外连接

sql 复制代码
-- inner ON 子句: 显示的是所有匹配的信息
select * 
from emp e 
inner join dept d
on(e.deptno = d.deptno);

select * from dept;
select * from emp;
-- 问题;40号部门没有员工,没有显示

-- 外连接 除了匹配的数据,还显示不匹配的数据
-- 左外连接 left outer join 左面表的信息
select * 
from emp e 
left outer join dept d
on(e.deptno = d.deptno);

-- 右外链接
select * 
from emp e 
right outer join dept d
on(e.deptno = d.deptno);

-- 全连接 full mysql不知道,oracle 支持

select * 
from emp e 
full outer join dept d
on(e.deptno = d.deptno);

-- 解决MySQL不支持 full的问题

select * 
from emp e 
left outer join dept d
on(e.deptno = d.deptno)
union -- 并集 去重
select * 
from emp e 
right outer join dept d
on(e.deptno = d.deptno);


select * 
from emp e 
left outer join dept d
on(e.deptno = d.deptno)
union all -- 并集 不去重
select * 
from emp e 
right outer join dept d
on(e.deptno = d.deptno);

-- mysql 支持并集,不支持交集,差集(oracle支持)
相关推荐
零陵上将军_xdr2 小时前
MySQL 事务写入流程详解
android·数据库·mysql
若阳安好2 小时前
【提效小工具】IN SQL、UPDATE SQL、INSERT SQL
java·数据库·sql
二月十六2 小时前
SQL Server 2022 新函数:DATETRUNC 日期截断详解
数据库·sqlserver·datetrunc
乐之者v2 小时前
20多个表,每个都有userId 和其他几个属性,要根据userId把他们全部汇总,如何处理?
java·mysql
qq_380619163 小时前
SQL中如何实现特定范围内数据的批量删除_范围分区与分区删除
jvm·数据库·python
qq_380619163 小时前
HTML函数开发需要独立显卡吗_HTML函数与显卡关系详解【说明】
jvm·数据库·python
电商API&Tina3 小时前
1688 拍立淘接口(item_search_img)测试与接入实战心得
java·大数据·前端·物联网·oracle·json
2201_756847333 小时前
Golang如何处理JSON空值null_Golang JSON空值处理教程【精通】
jvm·数据库·python