MySQL常用语句大全
前言
- 在windows系统下,mysql数据库不区分大小写。
- 在linux系统下,mysql数据库区分大小写的!
即使你在Windows下使用MySQL,为了养成良好习惯,还是区分大小写,方便代码迁移!关键字全部使用大写🔠
单行注释:
--
或者#
(#是MySQL特有的)多行注释:
/**/
备注:
[]
这在本文中表示可要可不要,这是博主自己的标记!- 表中的列称属性,也称字段、数据项
- 表中的行称元组,也称记录、分量
推荐阅读:
- 数据库系统概论
- Redis学习笔记
PS:从这张图,你应该就能猜到我是从哪里学习的MySQL了吧(●ˇ∀ˇ●)
一、DDL
DDL(Data Definition Language):数据定义语言,用来对数据库中的数据对象的组成和结构进行定义。
操作对象 | 操作方式 | ||
创建 | 删除 | 修改 | |
模式 | CREATE SCHEMA | DROP SCHEMA | —————— |
表 | CREATE TABLE | DROP TABLE | ALTER TABLE |
视图 | CREATE VIEW | DROP VIEW | —————— |
索引 | CREATE INDEX | DROP INDEX | ALTER INDEX |
1、操作数据库
1.1 查询数据库
#1.查询MySQL中所有的数据库
SHOW DATABASES;
#2.查询当前正在使用的数据库
SELECT DATABASE();
1.2 创建数据库
#1.普通创建(创建已经存在的数据库会报错)
CREATE DATABASE 数据库名称;
#2.创建并判断(该数据库不存在才创建)
CREATE DATABASE IF NOT EXISTS 数据库名称;
# 创建一个数据库,并指定字符集
create database itheima default charset utf8mb4;
1.3 删除数据库
#1.普通删除(删除不存在的数据库会报错)
DROP DATABASE 数据库名称;
#2.删除并判断(该数据库存在才删除)
DROP DATABASE IF EXISTS 数据库名称;
1.4 使用数据库
USE 数据库名称;
2、操作表
1.1 创建(CREATE)
CREATE TABLE 表名(
字段名1 数据类型,
字段名2 数据类型,
...
字段名n 数据类型 -- 最后一行不能加逗号!
);
1.2 查询(RETRIEVE,检索)
#1.查询当前数据库中所有表的名称
SHOW TABLES;
#2.查询表的结构
DESC 表名;
#3.查看建表语句(还能查看到建表时没写的默认参数)
show create table 表名;
1.3 修改(ALTER)
#1.修改表名
ALTER TABLE 表名 RENAME TO 新的表名;
#2.添加一列
ALTER TABLE 表名 ADD 列名 数据类型 [ COMMENT 注释 ];
#3.修改某列(字段)数据类型
ALTER TABLE 表名 MODIFY 列名 新的数据类型;
#4.修改列名和数据数据类型
ALTER TABLE 表名 CHANGE 旧列名 新列名 新数据类型 [ COMMENT 注释 ];
#5.删除列(字段)
ALTER TABLE 表名 DROP 列名;
1.4 删除(DROP)
#1.普通删除(删除不存在的表会报错)
DROP TABLE 表名;
#2.删除并判断(该表存在才删除)
DROP TABLE IF EXISTS 表名;
#3.删除指定表并重新创建(相当于清空表中的数据)
TRUNCATE TABLE 表名;
二、DML
DML(Data Manipulation Language):数据操作语言,用来对数据库库中表的数据进行增、删、改
1、添加数据(INSERT)
#1.给指定列添加数据
INSERT INTO 表名(列名1,[列名2],[...)VALUES(值1,[值2],[...]); -- 值1对应列名1,...
#给全部列添加数据(相当于添加新的一行)
INSERT INTO 表名[所有列名] VALUES(值1,值2,...);
-- []中表示可以省略,省略时默认按顺序填写字段,不建议省略
#3.批量添加数据
INSERT INTO 表名(列名1,[列名2],[...])VALUES(值1,值2,...),[(值1,值2,...)],[...];
#批量给全部列添加数据(相当于添加新的多行)
INSERT INTO 表名[所有列名] VALUES(值1,值2,...),(值1,值2,...),...;
2、修改数据(UPDATE)
#1.修改数据
UPDATE 表名 SET 列名1=值1,[列名2=值2],[...][WHERE 条件];
-- 注意:如果不使用WHERE条件,会将表中所有数据进行修改!
3、删除数据(DELETE)
DELETE FROM 表名 [WHERE 条件];
-- 注意:如果不使用WHERE条件,会将表中所有的数据删除!
三、DQL
DQL(Data Query Language):数据查询语言,用来查询数据库中表的数据。
DQL编写顺序:
#查询语法:
SELECT 字段列表
FROM 表名列表
WHERE 条件列表
GROUP BY 分组字段
HAVING 分组后条件
ORDER 排序字段
LIMIT 分页限定
DQL执行顺序:
1、基础查询
#1.查询字段
SELECT 字段1,[字段2],[...] FROM 表名;
SELECT * FROM 表名 ;-- 查询表中所有字段
-- 注意:查询表中所有字段虽然可以使用*,但是推荐使用字段列表(更加清晰)
#2.去除重复记录
SELECT DISTINCT 字段1,[字段2],[...] FROM 表名;
#3.起别名
SELECT 字段1 AS 别名1,[字段2 AS 别名2],[...] FROM 表名;
-- 注意:起别名的关键字AS可以省略,但是别名和字段名要有空格隔开
AS
:可以给字段或表起别名,通常该关键字可以省略,但是要别名和 字段/表 要用空格隔开
2、条件查询
SELECT 字段1,[字段2],[...] FROM 表名 WHERE 条件列表;
条件运算符:
2.1 模糊查询
模糊查询使用关键字
LIKE
,同时需要了解常用的通配符:
%
(百分号):表示任意长度的字符串,例如:a%表示,以a开始后面接任意长度的字符串_
(下划线):表示任意单个字符,例如:a_表示,以a开始后面只能接一个字符
示例:
#从Student表中查询姓马的人
SELECT * FROM Student WHERE Name LIKE '马%';
#从Student表中查询名字第二个字是花的人
SELECT * FROM Student WHERE Name LIKE '_花%';
##从Student表中查询名字中含有疼字的人
SELECT * FROM Student WHERE Name LIKE '%疼%'
2.2 排序查询
排序查询使用关键字
ORDER BY
,同时需要了解常用的排序方式:
ASC
(ascending order):升序排序(MySQL默认的排序方式)DESC
(descending order):降序排序备注:升序、降序是自上而下的。当使用两个排序条件时,只有前面的条件值一样时,才会根据第二个排序条件进行排序
SELECT 字段1,[字段2],[...] FROM 表名 ORDER BY 排序字段1 排序方式,[排序字段2 排序方式],[...]
-- 注意:排序字段1不等于字段1,排序字段1是从前面的查询的字段中选中一个出来,然后按照排序方式显示出来
示例:
#从sudent表中查询学生信息,按照年龄进行升序排列
SELECT * FROM student ORDER BY Sage [ASC];
#从sudent表中查询学生信息,按照年龄进行降序排列
SELECT * FROM student ORDER BY Sage DESC;
#从sudent表中查询学生信息,按照数学成绩进行升序排列,如果遇到多个学生数学成绩一样,就按找英语成绩进行降序排列
SELECT * FROM student ORDER BY Math DESC,English ASC;
3、 聚合函数
在学习分组查询前,我们需要先了解聚合函数,聚合函数的作用就是:是查询功能更加强大,同时方便用户使用。
函数名 | 功能 |
---|---|
`COUNT([DISTINCT | ALL] 列名)` |
`MAX([DISTINCT | ALL] 列名)` |
`MIN([DISTINCT | ALL] 列名)` |
`SUM([DISTINCT | ALL] 列名)` |
`AVG([DISTINCT | ALL] 列名)` |
备注:null不参与所有聚合函数的运算!!!
COUNT(*)
表示统计表的总行数,也可以使用主键的字段名
DISTINCT
:去除重复的值,即遇到重复的值不会加1ALL
:不去重(MySQL默认)
#聚合函数语法:
SELECT 聚合函数名([DISTINCT|ALL] 列名) FROM 表;
示例:
#从student表中查询所有学生的个数
SELECT COUNT(*) FROM student;-- 或者使用:SELECT COUNT(Sno) FROM student;
#从student表中查询参加了考试的人数
SELECT COUNT(Score) FROM student;-- 没参加考试,成绩就为null
#查询student表中,数学成绩最高分
SELECT MAX(Math) FROM student;
#查询student表中,数学成绩最低分
SELECT MIN(Math) FROM student;
#查询student表中,数学成绩平均分
SELECT AVG(Math) FROM student;
#查询student表中,全班数学成绩的总分
SELECT SUM(Math) FROM student;
4、 分组查询
分组查询使用关键字
GROUP BY
,可以让查询结果按照某一列或多列的值进行分组。分组的目的:为了细化聚合函数的作用对象
#分组查询的语法:
SELECT 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤];
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义!!!原因很简单,假如我们查询了其他字段,例如我们对性别进行了分组,然后查询名字,那么它最终只会显示两个名字,我们本意查名字是查全部名字,使用分组后只有两个,和我们的本意相违背
WHERE和HAVING的区别:
- 执行时机不一样:WHERE是分组之前进行限定,不满足WHERE条件,则不参与分组,而HAVING是分组之后对结果进行过滤
- 可判断的条件不一样:WHERE不能对聚合函数进行判断,HAVING可以
示例:
#查询男同学和女同学各自的数学平均分
SELECT sex, AVG(math) FROM stu GROUP BY sex;
SELECT name, sex, AVG(math) FROM stu GROUP BY sex; -- 这里查询name字段就没有任何意义
#查询男同学和女同学各自的数学平均分,以及各自人数
SELECT sex, AVG(math),COUNT(*) FROM stu GROUP BY sex;
#查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组
SELECT sex, AVG(math),COUNT(*) FROM stu WHERE math > 70 GROUP BY sex;
#查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组,分组之后人数大于2个的
SELECT sex, AVG(math),COUNT(*) FROM stu WHERE math > 70 GROUP BY sex HAVING COUNT(*) > 2;
5、分页查询
分页查询使用关键字
LIMIT
,该关键字是MySQL数据库的方言,在Oracle中分页查询使用关键字ROWNUMBER
,SQL Server分页查询使用关键字TOP
。
SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询条目数;
注意:索引是从0开始的,和数组中的索引是一样的
示例:
#查询student表中前三条记录
SELECT * FROM student LIMIT 0,3;
6、多表查询
在实际工作中多表查询是最最最常见的,在学习多表查询前需要先了解一下关系代数。
推荐阅读:数据库学习之关系代数
#查询多张表的所有数据
SELECT * FROM 表1,表2,... [WHERE 条件];
-- 查询结果是多张表的笛卡尔积
6.1 内连接
内连接是查询多张表的交集数据。它是从多张表中查询出满足条件的待查询字段数据,就是多张表先要满足给定的条件,等条件筛选后再进行查询。
#隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;
#显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 [JOIN ...] ON 条件;
6.2 外连接
外连接就算查询一个表的所有数据和满足条件的其他表数据。
外连接分为:
- 左外连接:查询A集合的所有数据以及满足条件的B集合数据
- 右外连接:查询B集合的所有数据以及满足条件的A集合数据
备注:两者可以互换
#左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
#右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
6.3 自连接
6.4 联合查询
7、子查询
查询中嵌套查询,我们称之为嵌套查询也称子查询。使用子查询可以减少SQL语句。
7.1 标量查询
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
7.2 列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询
7.3 行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
7.4 表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询。
-
子查询根据查询结果不同,作用不同:
-
子查询语句结果是单行单列,子查询语句作为条件值,使用 = 、 != 、 > 、 < 等进行条件判断
SELECT 字段列表 FROM 表 WHERE 字段名 条件符 (子查询); -- 如果条件判断使用or则是多行单列 -- 如果字段列表使用*则是多行多列
-
子查询语句结果是多行单列,子查询语句作为条件值,使用
IN
等关键字进行条件判断SELECT 字段列表 FROM 表 WHERE 字段名 IN (子查询); -- 如果字段列表使用*则是多行多列
-
子查询语句结果是多行多列,子查询语句作为虚拟表
SELECT 字段列表 FROM (子查询) WHERE 条件;
-
示例:
#单行单列
-- 查询 '财务部'的员工的姓名
select name emp where id = (select did from dept where dname = '财务部');
#多行单列
-- 查询 '财务部' 或者 '市场部' 的员工的部门姓名
select name from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
#多行多列
-- 查询入职日期是 '2011-11-11' 之后的员工信息,使用*结果是多行多列
select * from emp where join_date > '2011-11-11' ;
-- 将上面语句的结果作为虚拟表和dept表进行内连接查询
select * from (select * from emp where join_date > '2011-11-11' ) t1, dept where t1.dep_id = dept.did;
四、DCL
DCL(Data Control Language):数据控制语言,用来定义数据库中的访问权限和安全即别,以及创建用户
备注:这类SQL开发人员用的比较少,主要是DBA(数据库管理员)使用
1、管理用户
# 查询用户
select * from mysql.user;
# 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
# 修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ;
# 删除用户
DROP USER '用户名'@'主机名' ;
2、管理权限
MySQL中定义了很多种权限,但是常用的就以下几种:
# 查询权限
SHOW GRANTS FOR '用户名'@'主机名' ;
# 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
# 撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
五、约束
约束就是对表中列上的数据进行相应的约束,确保数据的正确性,有效性和完整性。约束语句可归为DDL。
SQL约束分类:
约束名 | 作用 | 关键字 |
---|---|---|
非空约束 | 保证列的所有数据不能为null | NOT NULL |
唯一约束 | 保证列的所有数据不重复 | UNIQUE |
主键约束 | 保证列的所有数据非空且唯一(主键是一行数据的唯一标识) | PRIMARY KEY |
检查约束 | 保证列中的值满足某一条件 | CHECK |
默认约束 | 设置列中数据的默认值 | DEFAULT |
外键约束 | 保证数据的一致性和完整性(外键用来连接两个表) | FOREIGN KEY |
AUTO_INCREMENT
:自动增长,当列是数字类型并且具有唯一约束时可以使用自增约束
注意:
-
MySQL不支持检查约束!!!
-
默认约束只有在不给值时才会采用默认值,如果给了null,那值就是null值(null也是一个值,只是为空而已)
外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性
外键约束的常用作用:
- 实现表的一对多的关系:在多的一方建立一个外键,关联一的一方的主键
- 实现表的一对一的关系:在任意一方建立一个外键,关联另一方的主键,同时外键要添加唯一约束
- 实现表的多对对的关系:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
示例:
# 建表时添加约束
-- 员工表emp
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT, -- 员工id,主键且自增长
ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一
joindate DATE NOT NULL , -- 入职日期,非空
salary DOUBLE(7,2) NOT NULL , -- 工资,非空
bonus DOUBLE(7,2) DEFAULT 0, -- 奖金,如果没有奖金默认为0
/*[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)*/
CONSTRAINT deptID FOREIGN KEY(id) REFERENCES dept(id)
-- 注意:使用外键约束,必须先创建主表,添加、删除数据时也是一样,否则会报错
);
# 建表后添加约束(只能一次给一个字段的添加一个约束)
#非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL; -- 添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型; -- 删除非空约束
#唯一约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE; -- 添加唯一约束
ALTER TABLE 表名 DROP INDEX 字段名; -- 删除唯一约束
#主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名); -- 添加主键约束
ALTER TABLE 表名 DROP PRIMARY KEY; -- 删除主键约束
#默认约束
ALTER TABLE 表名 ALTER 字段名 SET DEFAULT 默认值; -- 设置默认值约束
ALTER TABLE 表名 ALTER 字段名 DROP DEFAULT; -- 删除默认值约束
#外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表字段名称); -- 添加外键约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称; -- 删除外键约束
-
删除/更新 行为:添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为,常见的有以下几种
六、函数
1、 字符串函数
2、 数值函数
3、 日期函数
4、 流程函数
七、事务
数据库的事务(Transaction)是一种机制、一个操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位,同时事务也是并发控制的基本单位。
注意:MySQL的事务是跟引擎有直接关系的,一般带事务的MySQL使用的引擎都是InnoDB,MySQL5.5版本后默认都是使用InnoDB存储引擎
1、 事务的常见操作
事物的ACID特性:
- 原子性(Atomicity):事物是数据库的不可分割的逻辑工作单位,要么全做,要么全不做
- 一致性(Consistency):事物的执行结果必须使数据库从一个一致性状态转变成另一个一致性状态。比如,数据库中有两个用户,张三和李四,张三向李四转账,转账后总的资金是保持不变的
- 隔离性(Isolation):一个事物的执行不能被其他事物干扰
- 持续性(Durability,也称永久性 Permanence ):事物一旦提交或回滚,它对数据库的改变是永久的
# 查看事务的提交方式
SELECT @@autocommit ;
# 设置事务的提交方式(0表示手动提交事务)
SET @@autocommit = 0 ;
# 开启事务
START TRANSACTION 或 BEGIN ;
#开启事务
BEGIN; -- 或者使用START TRANSACTION开启事务
#提交事务
COMMIT;
#回滚事务
ROLLBACK; -- 恢复到事物开始前
备注:MySQL的事务默认是自动提交的,Oracle的事务默认是手动提交的
SET @@AUTOCOMMIT = 0|1
:设置事务的默认提交方式
1
:表示事务自动提交0
:表示事务手动提交
SELECT @@AUTOCOMMIT
:查询事务的默认提交方式
示例:
begin;
# --------------开始事务-----------------------
update account set money = money - 500 where name = "张三";
if((select money from account where name = "张三")<500) then
rollback; -- 撤销掉开始事物后的更新操作,将表恢复到事物前的状态
else -- 如果张三的账户余额大于等于500就进行转账操作
update account set money = money + 500 where name = "李四";
# --------------结束事务-----------------------
commit; # 事务执行过程中没有出现异常,则直接提交事务,数据库更新数据
rollback; # 事务执行过程中没有出现异常,回滚事务(回答事务执行前的状态)
2、 并发性事务问题
MySQL中事务拥有四种隔离级别,在并发场景下,不同的隔离级别存在不同的问题
# 查看事务的隔离级别
SELECT @@TRANSACTION_ISOLATION;
# 设置事务的隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
-- 示例
set session transaction isolation level 设置事务隔离级别
# 设置read uncommitted级别:
set session transaction isolation level read uncommitted;
# 设置read committed级别:
set session transaction isolation level read committed;
# 设置repeatable read级别:
set session transaction isolation level repeatable read;
# 设置serializable级别:
set session transaction isolation level serializable;
设存在一个事务A,一个事务B
- 读未提交(Read Uncommitted):指事务未成功提交的数据也能够被其它事务所读取,存在脏读、不可重复读、幻读问题
- 读已提交(Read Committed):指只有事务提交成功后的数据才能够被其它事务所读取,存在不可重复读、幻读问题
- 可重复读(Repeatable Read):指事务开始读取到的数据和事务结束前读取到的数据必须保持一致,存在幻读问题
- 串行化(Serializable):在每个读的数据行上,加上锁,使之不可能相互冲突,但是性能很低,容易发生请求超时和请求堆积问题
从上往下,隔离强度逐渐增强,性能逐渐变差。MySQL默认的隔离级别是可重复读,而Oracle的默认隔离级别是读已提交
- 脏读(Dirty Read):读到无效数据。比如,事务A对 viewCount 字段进行了一个更新操作,事务A还未提交,此时事务B对 viewCount 字段进行一个查询,但是在B读取数据后,事务A进行了一个回滚
- 不可重复读(Unrepeatable read):指同一事务中多次查询同一字段,出现数据不一致。通常针对数据更新(UPDATE)操作
- 幻读(Phantom Read):指的是同一个事务中在前后两次查询中,后一次的查询里面,出现了前一次查询没有查到的记录。换句话说,一个事务在进行查询操作时,未查询到该记录,但是进行插入操作时,该数据又存在了,就像出现幻觉一样。比如,假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读。针对数据插入(INSERT)操作
参考文章:
必备站点:
最后在此致谢黑马💖,本笔记是依据黑马程序员 MySQL数据库入门到精通-哔哩哔哩编写的(其中的一些截图也是摘抄自黑马的),这个课程质量不错,讲的也挺细,值得推荐,最后送还在迷茫的你一句话“肝就完了”😄