JAVA入门基础_从零开始的培训_MYSQL基础

1、数据库概述 与 MYSQL5.7、MYSQL8.0 安装篇(基于Windows)

MYSQL是什么,为什么要使用MYSQL

  • MYSQL是一个关系数据库管理系统(RDBMS),我们可以把MYSQL理解为一个管理程序,它管理着我们的一个个数据库。打比方:MYSQL就好比WORD程序,数据库就好比使用WORD程序打开的一个个.docx文档。
  • MYSQL主要是性能卓越、开放源代码、用户群体广泛、主要还有免费版
  • MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持 4GB ,64位系统支持最大的表文件为 8TB 。

MYSQL的四个版本

  • 社区版(GPL),免费
  • General Public License,GNU通用公共许可协议,软件可以自由使用,修改源代码都是允许的。
  • 集群社区版(免费)
  • 商业版(收费)
  • 集群商业版(收费)

MYSQL环境搭建

MYSQL的安装与卸载

Windows10 下安装MYSQL 8.26版本

  • 下载地址
  • 双击下载好的安装包: mysql-installer-community-8.0.26.0.msi
  • 选择自定义安装,Custom
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 将产品移动到需要安装的右侧
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 点一下移动到右侧的产品,点Advanced Options高级选项
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 设置MYSQL安装位置以及数据库存放的位置
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 一路next,最后点击Execute执行
  • 继续点击next,进行MYSQL的配置
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 继续点击next,使用新的认证授权方式,再点确定
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 设置root的密码(我这里是abc123)后点击next
  • 设置服务名称、开机是否自启动等,设置好后点击next
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 最后点击Execute执行,然后一路确认即可。
配置环境变量
  • 找到并复制MYSQL8安装的路径中的bin路径,我这里是这个: D:\a_dev_software\MYSQL\MySQL Server 8.0\bin
  • 将其添加到系统环境变量中的path当中
    JAVA入门基础_从零开始的培训_MYSQL基础

Windows10 下安装MYSQL 5.7版本(属于安装2个MYSQL版本)

  • 下载地址
  • 双击下载好的安装包: mysql-installer-community-5.7.34.0.msi
  • 页面弹出后,直接点击右下角的cancel取消,确认
  • 在页面中选择add
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 将产品移动到需要安装的右侧
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 点一下移动到右侧的产品,点Advanced Options高级选项
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 设置MYSQL安装位置以及数据库存放的位置
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 一路next,最后点击Execute执行
  • 继续点击next,进行MYSQL的配置(端口记得换,不能2个MYSQL都用一个端口)
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 点击next,设置root的密码(我这里是abc123)后点击next
  • 设置服务名称、开机是否自启动等,设置好后点击next
    JAVA入门基础_从零开始的培训_MYSQL基础
  • 最后点击Execute执行,然后一路确认即可。安装完成最后可以看到如下页面
    JAVA入门基础_从零开始的培训_MYSQL基础

MYSQL的卸载步骤

  1. 在服务面板停止MYSQL服务
  2. 在控制面板找到MYSQL,将其卸载
  3. 找到数据库文件,可以自由选择是否删除
  4. 删除对应的环境变量
  5. 如果是MYSQL5.7,则需要删除如下注册表,win + r后输入regedit回车即可进入注册表管理界面
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MySQL服务 目录删除
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\Eventlog\Application\MySQL服务 目录删除
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\MySQL服务 目录删除
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MySQL服务目录
删除
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL服务删除

MYSQL的环境问题

登录到MYSQL

mysql -uroot -pabc123 -P3306 -hlocalhost

-u用户名
-p密码
-P端口
-h目标主机,localhost代表本机

解决MYSQL5.7中的中文乱码问题 | 8.0的数据库不用修改

  • 原因:MYSQL5.7中的默认编码字符集为 latin1,并不支持我们的中文,因此我们需要将其修改为 UTF-8
  • 使用命令查看系统编码(要登录到mysql才行)
查看系统的默认字符集
show variables like 'character_%';

查看系统的比较规则字符集(理解为数据的比较字符集)
show variables like 'collation_%';

JAVA入门基础_从零开始的培训_MYSQL基础
JAVA入门基础_从零开始的培训_MYSQL基础
  • 找到MYSQL 5.7数据目录中的my.ini文件
63行左右,在[mysql]下添加默认字符集
[mysql]
default-character-set=utf8 #默认字符集

在76行左右,在[mysqld]下添加如下内容
character-set-server=utf8 # 设置服务器的字符集
collation-server=utf8_general_ci # 设置比较规则
  • 重启MYSQL5.7的服务即可
  • 小提示:已经创建好的数据库、数据表的字符集不会被更改,需要自行修改
alter table 表名 charset utf8; #修改表字符编码为UTF8

alter table 表名 modify 字段名 字段类型 charset utf8; #修改字段字符编码为UTF8

alter database 数据库名 charset utf8; #修改数据库的字符编码为utf8

登录MYSQL8,执行如下语句

#使用mysql数据库
USE mysql;

#修改'root'@'localhost'用户的密码规则和密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'abc123';

#刷新权限
FLUSH PRIVILEGES;

MYSQL忘记密码的还原办法

1: 通过任务管理器或者服务管理,关掉mysqld(服务进程)

2: 通过命令行+特殊参数开启(也可以直接在配置文件[mysqld]后加上skip-grant-tables)

mysqld --defaults-file="指定mysql的配置文件my.ini" --skip-grant-tables

3: 此时,mysqld服务进程已经打开。并且不需要权限检查

4: mysql -uroot 无密码登陆服务器。另启动一
个客户端进行

5: 修改权限表 (1) use mysql; (2)update user set authentication_string=password('新密
码') where user='root' and Host='localhost'; (3)flush privileges;

6: 通过任务管理器,关掉mysqld服务进
程。

7: 再次通过服务管理,打开mysql服务。 8: 即可用修改后的新密码登陆。

SQL的基本介绍

SQL是干什么的

  • SQL(Structured Query Language,结构化查询语言),用于跟数据打交道。在不同的数据库管理系统中,SQL可能会出现一些细微的差距。

SQL的分类

DDL 数据定义语言

CARETE、DROP、ALTER等

DML 数据操纵语言

INSERT、DELETE、UPDATE、SELECT

DCL 数据控制语言

GRANT、REVOKE、COMMIT、ROLLBACK、SAVEPOINT等

写SQL的一些提议

  1. SQL可以写单行或多行,注意可读性
  2. 字符串类型及日期类型,使用单引号 ''表示
  3. 在书写别名时,使用 as并且别名使用双引号包裹 ""
  4. 数据库名、表名、表别名、字段名、字段别名都使用 小写
  5. SQL关键字、函数名、绑定变量都 大写

MYSQL中的注释

单行注释

-- 单行注释

/*
多行注释
*/

2、SQL之SELECT使用篇、包含运算符

SELECT的查询结构(2种)

  • 第一种
SELECT ...,....,...

FROM ...,...,....

WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...

HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

  • 第二种
SELECT ...,....,...

FROM ... JOIN ...

ON 多表的连接条件
JOIN ...

ON ...

WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...

HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

对查询结构中参数的解释

  • (1)from:从哪些表中筛选
  • (2)on:关联多表查询时,去除笛卡尔积
  • (3)where:从表中筛选的条件
  • (4)group by:分组依据
  • (5)having:在统计结果中再次筛选
  • (6)order by:排序
  • (7)limit:分页

SELECT查询语句的执行顺序

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT 的字段 -> DISTINCT -> ORDER BY -> LIMIT
首先假设我们进行的查询是一个多表查询:

  1. 首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;
  2. 通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;
  3. 添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。

当然如果我们操作的是两张以上的表,还会 重复上面的步骤,直到所有表都被处理完为止。这个过程得到是我们的原始数据。

  1. 然后进入第三步和第四步,也就是 GROUP 和 HAVING 阶段 。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3 和 vt4 。
  2. 当我们完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT阶段 。首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表vt5-1 和 vt5-2 。
  3. 当我们提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段 ,得到虚拟表 vt6 。
  4. 最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段 ,得到最终的结果,对应的是虚拟表vt7 。

MYSQL中的运算符

算数运算符(7个)

  • +:加法
  • -:减法
  • *:乘法
  • / 或者 DIV:除法
  • % 或者 MOD:取模,取余时仅看被模数的正负号

比较运算符(19个)

  • =:等于
  • <=><!--=-->:安全等于,为null而生,可以比较null
  • <> 或者 !=: 不等于
  • <:小于
  • <=< code>&#xFF1A;&#x5C0F;&#x4E8E;&#x7B49;&#x4E8E;<!--=<-->
  • >:大于
  • >=:大于等于
  • IS NULL:判断是否为null
  • IS NOT NULL:判断是否不为null
  • ISNULL:判断是否为null的函数
  • LEAST:最小值运算符
  • GREATEST:最大值运算符
  • BETWEEN AND:判断一个值是否在两个值之间
  • IN:属于运算符,判断一个值是否为列表中任意一个值
  • NOT IN:不属于运算符,判断一个值是否不为列表中任意一个值
  • LIKE:模糊匹配, %代表多个任意字符, _一个任意字符
  • REGEXP:正则表达式运算符
  • RLIKE:正则表达式运算符

逻辑运算符(7个)

  • AND 或者 &&:逻辑与
  • OR 或者 ||: 逻辑或
  • NOT 或者 !:逻辑非
  • XOR:异或

位运算符(6个)

  • &:与
  • |: 或
  • ^:异或
  • <<:左移
  • >>:右移
  • >>>:无符号右移

使用运算符时的小问题记录

  • NULL值与任何值进行计算时, 结果都为NULL,除非使用
  • 字符串类型的数值在计算时,会 隐式转换成与其进行计算的数据类型,若是转换失败则将会被 转换为0,字符串与字符串进行比较时例外。
  • 当一个数除0,那么结果为NULL

MYSQL中的数据类型

所有的数据类型

类型 类型举例 整数类型 TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT 浮点类型 FLOAT、DOUBLE 定点数类型 DECIMAL 位类型 BIT 日期时间类型 YEAR、TIME、DATE、DATETIME、TIMESTAMP 文本字符串类型 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT 枚举类型 ENUM 集合类型 SET 二进制字符串类型 BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB JSON类型 JSON对象、JSON数组 空间数据类型 单值类型:GEOMETRY、POINT、LINESTRING、POLYGON;集合类型:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION

常见的数据类型可用属性

MySQL关键字 含义 NULL 数据列可包含NULL值 NOT NULL 数据列不允许包含NULL值 DEFAULT 默认值 PRIMARY KEY 主键 AUTO_INCREMENT 自动递增,适用于整数类型 UNSIGNED 无符号 CHARACTER SET name 指定一个字符集

数据类型中的一些细节

UNSIGNED对于整数型、浮点型的作用

  • 对于整数型: 将无法存储负数,且将数据存储范围扩大(扩大的大小就是负数的范围)。
  • 对于浮点型: 仅仅是无法存储负数。存储空间一样占用,存储范围没有变化。

MYSQL5.7整数类型的宽度显示作用

  • 设置了宽度仍然可以存储超越宽度的数值,所以需要配合上 ZEROFILL使用才有意义。
  • ZEROFILL : 整数位数不足宽度时,会往左侧补0。(添加此参数时,会同时默认添加UNSIGNED)

浮点数类型(m,n)的作用

  • 用于限制浮点数的 宽度m小数位数n
  • 宽度m包括小数位,例如:99.51的宽度m为4

DATETIME 和 TIMESTAMP的区别

  • TIMESTAMP存储空间比较小,表示的日期时间范围也比较小。
  • TIMESTAMP 底层存储的是毫秒值,计算速度更快。
  • TIMESTAMP 的日期时间会根据时区自动变换。

CHAR、VARCHAR、TEXT的使用建议

  • 当字符串长度固定或基本不变时,使用CHAR
  • 字符数不超过5000时,使用VARCHAR
  • 字符数大于5000时,使用TEXT并新建一个表进行存储,避免影响索引查询的效率
  • InnoDB存储引擎内部行的存储格式并 不区分固定长度与可变长度列, *影响性能的因素是数据行使用的存储总量。

选择数据类型的建议

  • 整数类型:一般采用INT
  • 小数类型:使用DECIMAL(M,D)
  • 日期时间:DATETIME
  • 字符串类型:略(上面有写)

原因:这样做的好处是,确保你的系统不会因为数据类型定义出错。 数据出错的代价远远高于占用的资源代价。

单行函数

数值型函数

函数名 函数作用 ABS(x) 求x的绝对值 SIGN(x) 判断x的值,大于0返回1,小于0返回-1,等于0返回0 PI() 圆周率 CEIL(x) 或 CEILING(x) 将x向上取整 FLOOR(x) 将x向下取整 LEAST(e1,e2,e3) 返回列表中的最小值 GREATEST(e1,e2,e3) 返回列表中最大值 MOD(x,y) x除y之后的余数 RAND() 返回0到1之间的伪随机数 RAND(x) 输入一个种子,依然返回0到1之间的伪随机数 ROUND(x) 返回x四舍五入后的值 ROUND(x,y) 返回x四舍五入后的值,小数保留y位(可以为负数) TRANCATE(x,y) 保留x的y位小数,多出的位数直接去除 SQRT(x) 求x的平方根,x为负数时返回NULL BIN(x) 返回x的二进制编码 HEX(x) 返回x的十六进制编码 OCT(x) 返回x的八进制编码 CONV(x,f1,f2) 返回f1进制数变成f2进制数,例如CONV(12, 8, 2)代表12是一个8进制,需要转换为2进制

字符串函数(SQL语言中字符串的索引从1开始)

函数名 函数作用 ASCII(s) 返回字符串s中第一个元素的ASCII码所代表的数字 CHAR_LENGTH(s) 或 CHARACTER_LENGTH(s) 返回x的字符数量 LENGTH(s) 返回s的字节数量 CONCAT(s1,s2,s3) 将列表中的数据拼接为一个字符串 CONCAT_WS(x,s1,s2,s3) 将列表中的数据拼接为一个字符串,其中x为连接符 insert(str,idx,len,replacestr) 将字符串str索引 idx的位置开始后的len个字符,替换成replacestr REPLACE(str,a,b) 将str字符串中的子集a替换成b UPPER(s) 或 UCASE(s) 将s转换为大写 LOWER(s) 或 LCASE(s) 将s转换为小写 LEFT(str,n) 获取字符串str从左开始的n个元素的子集 RIGHT(str,n) 获取字符串str从右开始的n个元素的子集 LPAD(str,n,pad) str如果不满足字符长度为n,则往左侧补pad填充到字符长度为n(相当于右对齐) RPAD(str,n,pad) str如果不满足字符长度为n,则往右侧补pad填充到字符长度为n(相当于左对齐) LTRIM(s) 去除s左侧的空格 RTRIM(s) 去除s右侧的空格 TRIM(s) 去除s左右二侧的空格 TRIM(s1 from s) 去除s左右两侧的s1 TRIM(LEADING s1 from s) 去除s左侧的s1 TRIM(LEADING s1 from s) 去除s左侧的s1 REPEAT(str,n) 返回str重复n次的结果 SPACE(n) 返回n个空格 STRCMP(str1,str2) 比较2个字符串之间的大小 SUBSTR(s,index,len) 或者 SUBSTRING(s,n,len) 或 MID(s,n,len) 返回s字符串中从index开始的len个元素 LOCATE(substr,str) 或者 POSITION(substr IN str) 或者 INSTR(str,substr) 获取str中substr第一次出现的索引位置 ELT(m,s1,s2,s3,s4) 返回指定位置的字符串,如果m为1,返回s1,m为2,返回s2 FIELD(s,s1,s2,s3,s4) 返回s在字符串列表中出现的位置 FIND_IN_SET(s,’s1,s2,s3,s4′) 返回s在字符串列表中出现的位置 REVERSE(s) 将字符串s反转 NULLIF(value1,value2) 如果2个值相等则返回null,否则返回value1

常用的多行函数

函数名 作用 AVG() 平均值,只适用于数值类型 SUM() 求和,只适用于数值类型 MAX() 最大值 MIN() 最小值 COUNT(字段名)、COUNT(1)、COUNT(*) 统计数量,注意COUNT(字段名)可能会统计不正确,因为不统计NULL值

时间日期函数(只列举常用)

获取日期、时间

1.&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7684;&#x65E5;&#x671F;&#x3001;&#x65F6;&#x95F4;&#x3001;&#x65E5;&#x671F;&#x65F6;&#x95F4;
SELECT CURDATE(),CURTIME(),NOW()
FROM DUAL

日期与时间戳的转换

2. &#x65E5;&#x671F;&#x4E0E;&#x65F6;&#x95F4;&#x6233;&#x7684;&#x8F6C;&#x6362;
2.1 &#x83B7;&#x53D6;&#x5F53;&#x524D;&#x65F6;&#x95F4;&#x6233;
SELECT UNIX_TIMESTAMP() FROM DUAL;
2.2 &#x83B7;&#x53D6;&#x6307;&#x5B9A;&#x65F6;&#x95F4;&#x7684;&#x65F6;&#x95F4;&#x6233;
SELECT UNIX_TIMESTAMP('2022-08-13 16:33:06') FROM DUAL;
2.3 &#x5C06;&#x65F6;&#x95F4;&#x6233;&#x8F6C;&#x6362;&#x4E3A;&#x65E5;&#x671F;
SELECT FROM_UNIXTIME(1660379586) FROM DUAL;

计算日期和时间的函数

3. &#x8BA1;&#x7B97;&#x65E5;&#x671F;&#x548C;&#x65F6;&#x95F4;&#x7684;&#x51FD;&#x6570;  DATEDIFF&#x3001;TO_DAYS&#x3001;DATE_ADD&#x3001;DATE_SUB
3.1 &#x8BA1;&#x7B97;2&#x4E2A;&#x65E5;&#x671F;&#x76F8;&#x5DEE;&#x7684;&#x5929;&#x6570;&#xFF0C;&#x5DE6;&#x8FB9;&#x51CF;&#x53F3;&#x8FB9;&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;3
SELECT DATEDIFF('2022-08-13', '2022-08-10') FROM DUAL;
3.2 &#x8BA1;&#x7B97;2&#x4E2A;&#x65F6;&#x95F4;&#x76F8;&#x5DEE;&#x7684;&#x65F6;&#x95F4;&#xFF0C;&#x5DE6;&#x51CF;&#x53F3;&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;06:05:28
SELECT TIMEDIFF('16:35:48', '10:30:20') FROM DUAL;
3.3 &#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#x8DDD;&#x79BB;0000&#x5E74;1&#x6708;1&#x65E5;&#x7684;&#x5929;&#x6570;(&#x6CE8;&#x610F;&#x662F;&#x5929;&#x6570;)
SELECT TO_DAYS('2000,01,01') FROM DUAL;
3.4 &#x4E3A;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#x65F6;&#x95F4; &#x589E;&#x52A0;&#x65E5;&#x671F;&#x65F6;&#x95F4;&#xFF0C;&#x7ED3;&#x679C;: 2022-08-15 16:33:06
SELECT DATE_ADD('2022-08-13 16:33:06',INTERVAL 2 DAY) FROM DUAL;
3.5 &#x4E3A;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#x65F6;&#x95F4; &#x51CF;&#x5C11;&#x65E5;&#x671F;&#x65F6;&#x95F4;&#xFF0C;&#x7ED3;&#x679C;: 2022-08-11 16:33:06
SELECT DATE_SUB('2022-08-13 16:33:06',INTERVAL 2 DAY) FROM DUAL;

日期的格式化与解析

4. &#x65E5;&#x671F;&#x7684;&#x683C;&#x5F0F;&#x5316;&#x4E0E;&#x89E3;&#x6790;
4.1 &#x5C06;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#x65F6;&#x95F4;&#x8FDB;&#x884C;&#x683C;&#x5F0F;&#x5316;, 2022/08/13 16:33:06
SELECT DATE_FORMAT('2022-08-13 16:33:06','%Y/%m/%d %H-%i-%S');
4.2 &#x83B7;&#x5F97;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#x65F6;&#x95F4;&#x7684;&#x683C;&#x5F0F;&#xFF0C;&#x6CE8;&#x610F;&#xFF0C;&#x65E5;&#x671F;&#x548C;&#x65F6;&#x95F4;&#x7684;&#x4E5F;&#x53EF;&#x4EE5;&#x83B7;&#x53D6;
SELECT GET_FORMAT(TIME, 'ISO') FROM DUAL;
4.3 &#x5C06;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x4E32;&#x8F6C;&#x6362;&#x4E3A;&#x65E5;&#x671F;&#x683C;&#x5F0F;
SELECT STR_TO_DATE('16:33:06',GET_FORMAT(TIME,'ISO')) FROM DUAL;

多表查询JOIN必须要会的一张图

JAVA入门基础_从零开始的培训_MYSQL基础
  • (1)左上图:相当于左外连接
  • (2)右上图:相当于右外连接
  • (3)中图:相当于内连接
  • (4)左中图:相当于左外连接不要中间的部分。
  • (5)右中图:相当于右外连接不要中间部分
  • (6)左下图:可以用左上图 UNION ALL 右中图 。 也可以用右上图 UNION ALL 左中图
  • (7)右下图:左中图 UNION ALL 右中图即可。

子查询的分类

按照查询的记录数量

  1. 单行子查询(子查询返回的只有 一条记录)
  2. 多行子查询(子查询返回的有 多条记录)

单行比较操作符

运算符 作用 = 相等 >= 大于等于 > 大于

多行比较操作符

运算符 作用 IN 等于列表中任意一个 ANY 匹配列表中任意一个,需要配合单行比较操作符使用 SOME 等同于ANY ALL 匹配列表中所有的值,需要配合单行比较操作符使用

按内查询是否被执行多次

  1. 不相关子查询(每次都是 固定的返回结果
  2. 相关子查询(每一次的查询都需要依靠 外查询来提供查询条件

SELECT 查询中遇到的问题记录

WHERE 与 HAVING的区别

WHERE 可以直接使用表中的字段作为筛选条件,但 不能使用分组中的计算函数作为筛选条件HAVING 必须要与 GROUP BY 配合使用,可以把 分组计算的函数和分组字段作为筛选条件。

EXISTS 与 NOT EXISTS的作用

EXISTS 通常用于 相关子查询,判断子查询中的数据是否符合条件,符合时返回1(true),不符合时返回0(false)。

NOT EXISTS与其恰恰相反。

使用IN 和 NOT IN的相关子查询通常可以改用 EXISTS 和 NOT EXISTS实现。

使用了GROUP BY 分组后,SELECT 的列表问题、WITH ROLLUP问题

  • 使用了GROUP BY 分组后,SELECT 列表只能放 聚合函数或进行了分组的字段
  • 当使用了ORDER BY 后,无法使用WITH ROLLUP,
  • WITH ROLLUP:在GROUP BY分组字段的基础上再进行统计数据,对数据进行求和。

3、SQL 之DDL、DML、DCL使用篇

数据库的增删改查

1. &#x521B;&#x5EFA;&#x6570;&#x636E;&#x5E93;
CREATE DATABASE IF NOT EXISTS my_db CHARACTER SET = 'UTF8';

2. &#x67E5;&#x8BE2;&#x6240;&#x6709;&#x7684;&#x6570;&#x636E;&#x5E93;
SHOW DATABASES;

3. &#x67E5;&#x770B;&#x6B63;&#x5728;&#x4F7F;&#x7528;&#x7684;&#x6570;&#x636E;&#x5E93;
SELECT DATABASE();

4. &#x67E5;&#x770B;&#x6307;&#x5B9A;&#x6570;&#x636E;&#x5E93;&#x4E0B;&#x6240;&#x6709;&#x7684;&#x8868;
SHOW TABLES FROM &#x6570;&#x636E;&#x8868;&#x540D;;

5. &#x67E5;&#x770B;&#x6570;&#x636E;&#x5E93;&#x7684;&#x521B;&#x5EFA;&#x4FE1;&#x606F;
SHOW CREATE DATABASE &#x6570;&#x636E;&#x5E93;&#x540D;

6. &#x4F7F;&#x7528;/&#x5207;&#x6362;&#x6570;&#x636E;&#x5E93;
USE &#x6570;&#x636E;&#x5E93;&#x540D;;

7. &#x4FEE;&#x6539;&#x6570;&#x636E;&#x5E93;&#x5B57;&#x7B26;&#x96C6;
ALTER DATABASE &#x6570;&#x636E;&#x5E93;&#x540D; CHARACTER SET = 'GBK';

8. &#x5220;&#x5E93;&#x8DD1;&#x8DEF;
DROP DATABASE IF EXISTS &#x6570;&#x636E;&#x5E93;&#x540D;&#x3002;

对数据表的增删改查

创建表的3种方式(包括创建临时表)

1. &#x767D;&#x624B;&#x8D77;&#x5BB6;&#x521B;&#x5EFA;
CREATE TABLE IF NOT EXISTS(
    &#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;&#x6761;&#x4EF6;] [&#x9ED8;&#x8BA4;&#x503C;],
    &#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;&#x6761;&#x4EF6;] [&#x9ED8;&#x8BA4;&#x503C;],
    &#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;&#x6761;&#x4EF6;] [&#x9ED8;&#x8BA4;&#x503C;]
);

2. &#x901A;&#x8FC7;&#x67E5;&#x8BE2;&#x7684;&#x8868;&#x6570;&#x636E;&#x521B;&#x5EFA;&#xFF08;&#x6CE8;&#x610F;&#x67E5;&#x8BE2;&#x8BED;&#x53E5;&#x5982;&#x679C;&#x6709;&#x522B;&#x540D;&#x4F1A;&#x4F7F;&#x7528;&#x522B;&#x540D;&#x4F5C;&#x4E3A;&#x65B0;&#x8868;&#x7684;&#x5B57;&#x6BB5;&#x540D;&#xFF09;
CREATE TABLE &#x9700;&#x8981;&#x521B;&#x5EFA;&#x7684;&#x8868;&#x540D;
AS
SELECT * FROM &#x8868;&#x540D;;

3. &#x521B;&#x5EFA;&#x4E34;&#x65F6;&#x8868;
&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x4E34;&#x65F6;&#x8868;
CREATE TEMPORARY TABLE &#x8868;&#x540D;
SELECT * FROM &#x8868;&#x540D;;

&#x5220;&#x9664;&#x4E00;&#x4E2A;&#x4E34;&#x65F6;&#x8868;
DROP TABLE &#x4E34;&#x65F6;&#x8868;&#x540D;;

查看建表语句以及表字段结构

&#x67E5;&#x770B;&#x5EFA;&#x8868;&#x8BED;&#x53E5;
SHOW CREATE TABLE &#x8868;&#x540D;;

&#x67E5;&#x770B;&#x8868;&#x5B57;&#x6BB5;&#x7ED3;&#x6784;
DESC &#x8868;&#x540D;&#x5B57;;

修改表

1. &#x8FFD;&#x52A0;&#x5217;
ALTER TABLE &#x8868;&#x540D;
ADD COLUMN &#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;] [&#x9ED8;&#x8BA4;&#x503C;] [AFTER|LAST|FIRST];

2. &#x4FEE;&#x6539;&#x5217;
ALTER TABLE &#x8868;&#x540D;
MODIFY &#x4FEE;&#x6539;&#x7684;&#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;] [&#x9ED8;&#x8BA4;&#x503C;] [AFTER|LAST|FIRST];

3. &#x91CD;&#x547D;&#x540D;&#x5217;
ALTER TABLE &#x8868;&#x540D;
CHANGE &#x4FEE;&#x6539;&#x7684;&#x5B57;&#x6BB5;&#x540D; &#x65B0;&#x5B57;&#x6BB5;&#x540D; &#x5B57;&#x6BB5;&#x7C7B;&#x578B; [&#x7EA6;&#x675F;] [&#x9ED8;&#x8BA4;&#x503C;] [AFTER|LAST|FIRST];

4. &#x5220;&#x9664;&#x5217;
ALTER TABLE &#x8868;&#x540D;
DROP COLUMN &#x5B57;&#x6BB5;&#x540D;;

5. &#x4FEE;&#x6539;&#x8868;&#x540D;
RENAME TABLE &#x539F;&#x8868;&#x540D; TO &#x4FEE;&#x6539;&#x540E;&#x7684;&#x8868;&#x540D;;

6. &#x5220;&#x9664;&#x8868;
DROP TABLE IF EXISTS &#x8868;&#x540D;;

7. &#x6E05;&#x7A7A;&#x8868;&#xFF08;&#x4F1A;&#x628A;&#x8868;&#x4E2D;&#x6570;&#x636E;&#x6E05;&#x7A7A;&#x5E76;&#x91CA;&#x653E;&#x5B58;&#x50A8;&#x7A7A;&#x95F4;&#xFF09;
TRUNCATE TABLE &#x8868;&#x540D;;

对于数据的增删改

增加数据的5种方式

&#x65B9;&#x5F0F;1
INSERT INTO &#x8868;&#x540D;
values(&#x5404;&#x5B57;&#x6BB5;&#x7684;&#x503C;);

&#x65B9;&#x5F0F;2&#xFF08;&#x63A8;&#x8350;&#xFF09;
INSERT INTO &#x8868;&#x540D;(&#x6307;&#x5B9A;&#x5B57;&#x6BB5;)
VALUES (&#x6839;&#x636E;&#x6307;&#x5B9A;&#x7684;&#x5B57;&#x6BB5;&#x586B;&#x5199;&#x503C;);

&#x65B9;&#x5F0F;3&#x3001;&#x6DFB;&#x52A0;&#x591A;&#x884C;&#x6570;&#x636E;
INSERT INTO &#x8868;&#x540D;(&#x6307;&#x5B9A;&#x5B57;&#x6BB5;)
VALUES
(&#x6839;&#x636E;&#x6307;&#x5B9A;&#x7684;&#x5B57;&#x6BB5;&#x586B;&#x5199;&#x503C;),
(&#x6839;&#x636E;&#x6307;&#x5B9A;&#x7684;&#x5B57;&#x6BB5;&#x586B;&#x5199;&#x503C;),
(&#x6839;&#x636E;&#x6307;&#x5B9A;&#x7684;&#x5B57;&#x6BB5;&#x586B;&#x5199;&#x503C;);

&#x65B9;&#x5F0F;4&#x3001;&#x5229;&#x7528;SELECT&#x5B9E;&#x73B0;&#x591A;&#x884C;&#x6570;&#x636E;&#x7684;&#x6DFB;&#x52A0;&#xFF0C;&#xFF08;&#x6CE8;&#x610F;SELECT&#x67E5;&#x8BE2;&#x51FA;&#x6765;&#x7684;&#x6570;&#x636E;&#x7C7B;&#x578B;&#x4E0E;&#x8868;&#x540D;&#x53EF;&#x4EE5;&#x5339;&#x914D;&#xFF09;
INSERT INTO &#x8868;&#x540D;(&#x6307;&#x5B9A;&#x5B57;&#x6BB5;)
SELECT &#x586B;&#x5199;&#x5B57;&#x6BB5;
FROM &#x8868;&#x540D;;

&#x4F8B;&#x5982;&#xFF1A;
    INSERT INTO t_test1
    SELECT last_name, salary
    FROM employees;

&#x65B9;&#x5F0F;5&#x3001;&#x4F9D;&#x7136;&#x662F;&#x5229;&#x7528;SELECT&#x5B9E;&#x73B0;&#x6570;&#x636E;&#x7684;&#x6DFB;&#x52A0;
INSERT INTO &#x8868;&#x540D;
SELECT &#x5B57;&#x6BB5;&#x5217;&#x8868;&#xFF0C;&#x9017;&#x53F7;&#x95F4;&#x9694; UNIOIN ALL
SELECT &#x5B57;&#x6BB5;&#x5217;&#x8868;&#xFF0C;&#x9017;&#x53F7;&#x95F4;&#x9694; UNIOIN ALL
SELECT &#x5B57;&#x6BB5;&#x5217;&#x8868;&#xFF0C;&#x9017;&#x53F7;&#x95F4;&#x9694;;

&#x4F8B;&#x5982;&#xFF1A;
    INSERT INTO t_teset1
    SELECT '&#x5F20;&#x4E09;',2000 union all
    SELECT '&#x674E;&#x56DB;',2500 union all
    SELECT '&#x738B;&#x4E94;',3000 ;

修改数据

UPDATE &#x8868;&#x540D;  SET &#x9700;&#x8981;&#x4FEE;&#x6539;&#x7684;&#x5B57;&#x6BB5;=&#x9700;&#x8981;&#x4FEE;&#x6539;&#x540E;&#x7684;&#x503C;  WHERE ..

删除数据的2种方式

&#x65B9;&#x5F0F;1
DELETE FROM &#x8868;&#x540D; WHERE ...

&#x65B9;&#x5F0F;2 &#x914D;&#x5408;SELECT&#xFF0C;&#x4F8B;&#x5982;&#x591A;&#x4E2A;&#x8868;&#x540C;&#x65F6;&#x5220;&#x9664;&#x67D0;&#x6761;&#x8BB0;&#x5F55;
&#x8BED;&#x6CD5;&#x793A;&#x4F8B;&#x5982;&#x4E0B;&#xFF1A;
DELETE e, d
FROM employee e
JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id = 10;
删除表中重复数据
DELETE FROM class_info
WHERE id IN (
    SELECT id FROM (
        SELECT id
        FROM class_info
        WHERE id NOT IN (
            SELECT MIN(id)
            FROM class_info
            GROUP BY class_name, class_leader
        )
    ) c
);

MYSQL表中对于数据及类型的约束

约束需要考虑的4个方面

约束就是为了保证数据的完整性,完整性指的是精确性和可靠类。

  • 实体完整性。同一个表中,不能出现2条无法区分的记录
  • 域完整性。指的是表中的字段能够存储的数据规范。提现在check 检查约束。
  • 引用完整性。例如:员工所在部门,那么必须存在该部门。提现在foreign key 外键。
  • 用户自定义完整性。例如:想要让用户名唯一,或者年龄不能为空等.

约束的分类

根据约束数据列的限制

  • 单列约束,每个约束只能约束一列。
  • 多列约束,每个约束可以约束多列。

根据约束的作用范围

  • 列级约束:约束作用于列上
  • 表级约束:约束作用于表上

常见的6个约束如下

  • NOT NULL 该列不能为空,列级约束
  • UNIQUE 唯一性约束,表级约束
  • PRIMARY KEY 主键约束(非空、唯一),无法更改约束名,表级约束
  • FOREIGN KEY 外键约束,表级约束。必须引用/参考主表的主键或唯一约束的列
  • 设置外键时可以指定 ON UPDATE/DELETE CASCADE/SET NULL ,分别代表更新或删除时,另一张关联表CASCADE共同删除或修改,SET NULL 设置为空
  • CHECK 检查约束,表级约束
  • DEFAULT 默认值,列级约束

查看某个表已有的表级约束

SELECT *
FROM information_schema.table_constraints
WHERE TABLE_NAME = 'employees';

添加、修改、删除列级约束

  • 添加列级约束
1. &#x901A;&#x8FC7;&#x521B;&#x5EFA;&#x8868;&#x7684;&#x65B9;&#x5F0F;
CREATE TABLE t_test1 (
    name VARCHAR(12) NOT NULL,
    age INT
)

2. &#x901A;&#x8FC7;ALTER MODIFY&#x7684;&#x65B9;&#x5F0F;
ALTER TABLE t_test1
MODIFY age INT NOT NULL;
  • 修改列级约束
ALTER TABLE t_test1
MODIFY age INT DEFAULT 10;
  • 删除列级约束(其实就是ALTER MODIFY 该字段不写约束即可)
ALTER TABLE t_test1
MODIFY age INT;

添加、删除表级约束(check在MYSQL5.7不支持)

  • 添加表级约束
1. &#x901A;&#x8FC7;&#x521B;&#x5EFA;&#x8868;&#x65F6;&#x6307;&#x5B9A;
&#x63D0;&#x793A;&#xFF1A;constriant&#x5C31;&#x662F;&#x4E3A;&#x4E86;&#x7ED9;&#x8868;&#x7EA6;&#x675F;&#x53D6;&#x540D;&#x3002;&#x5BF9;&#x4E3B;&#x952E;&#x65E0;&#x6548;&#x3002;&#x4E0D;&#x53D6;&#x540D;&#x5219;&#x9ED8;&#x8BA4;&#x4E3A;&#x5B57;&#x6BB5;&#x540D;(check&#x7684;&#x9ED8;&#x8BA4;&#x683C;&#x5F0F;&#x4E3A; &#x8868;&#x540D;_chk_1&#xFF0C;&#x8868;&#x540D;_chk_2&#xFF0C;&#x5916;&#x952E;&#x7684;&#x4E3A;&#xFF1A;&#x8868;&#x540D;_ibfk_1)&#x3002;

CREATE TABLE test_2(
    id INT,
    name VARCHAR(12),
    t_test1_id INT,
    age INT,
    birthday DATE,
    CONSTRAINT fk_id FOREIGN KEY (t_test1_id) REFERENCES t_test1(id),
    PRIMARY KEY(id),
    CHECK (age > 10),
    UNIQUE KEY(name)
)

2. &#x901A;&#x8FC7;ALTER ADD &#x6DFB;&#x52A0;

ALTER TABLE test_2
ADD CONSTRAINT chk_age CHECK(age < 20);
  • 删除表级约束(根据约束名)
1&#x3001; &#x5220;&#x9664;&#x4E3B;&#x952E;&#x7EA6;&#x675F; &#x548C; &#x552F;&#x4E00;&#x7EA6;&#x675F;
ALTER TABLE test_2
DROP INDEX PRIMARY;

ALTER TABLE test_2
DROP INDEX name;

2&#x3001;&#x5220;&#x9664;&#x68C0;&#x67E5;&#x7EA6;&#x675F;
ALTER TABLE test_2
DROP CHECK test_2_chk_1;

3&#x3001;&#x5220;&#x9664;&#x5916;&#x952E;&#x7EA6;&#x675F;
ALTER TABLE test_2
DROP FOREIGN KEY fk_id;

4、其他数据库对象篇

视图

视图的创建与使用

&#x521B;&#x5EFA;&#x89C6;&#x56FE;
CREATE VIEW vu_sal
AS
SELECT * FROM employees;

&#x4F7F;&#x7528;&#x89C6;&#x56FE;
SELECT * FROM vu_sal;

视图的原理

  • 视图其实就是一张虚拟表,视图中不存储数据
  • 可以把视图理解为一个存储起来的SELECT查询
  • 对视图的修改就相当于对于基表的修改
  • 对视图进行一条数据数据修改时,该条数据必须与基表中的数据一对一对应

存储过程与存储函数

存储过程

存储过程的创建与调用(IN、OUT、INOUT)

IN 、OUT的同时使用
&#x521B;&#x5EFA;&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;format_date(),&#x5B9E;&#x73B0;&#x4F20;&#x5165;&#x4E00;&#x4E2A;&#x65E5;&#x671F;&#xFF0C;&#x683C;&#x5F0F;&#x5316;&#x6210;xx&#x5E74;xx&#x6708;xx&#x65E5;&#x5E76;&#x8FD4;&#x56DE;
delimiter $

CREATE PROCEDURE format_date(IN my_date DATE, OUT res VARCHAR(32))
BEGIN
        SELECT  DATE_FORMAT(my_date, GET_FORMAT(DATE,'ISO')) INTO res
        FROM DUAL;
END $

delimiter ;

set @my_date = '2020/10/20';
CALL format_date(@my_date, @res);
SELECT(@res) FROM DUAL;
INOUT的使用
&#x4F20;&#x5165;a&#x548C;b&#x4E24;&#x4E2A;&#x503C;&#xFF0C;&#x6700;&#x7EC8;a&#x548C;b&#x90FD;&#x7FFB;&#x500D;&#x5E76;&#x8FD4;&#x56DE;&#x3001;&#x521B;&#x5EFA;&#x5E26;inout&#x6A21;&#x5F0F;&#x53C2;&#x6570;&#x7684;&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;
DELIMITER $
CREATE PROCEDURE calculate_num(INOUT a INT, INOUT b INT)
BEGIN
        SELECT a * 2 INTO a;
        SELECT b * 2 INTO b;

END $
DELIMITER ;

&#x8C03;&#x7528;
set @a = 2;
set @b = 6;
CALL calculate_num(@a, @b);
SELECT @a FROM DUAL;
SELECT @b FROM DUAL;
删除存储过程
DROP PROCEDURE &#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x540D;;
查看存储过程的信息(3种方式)
SHOW CREATE PROCEDURE &#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x540D;;

SHOW PROCEDURE STATUS LIKE '&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x540D;';

SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME='&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x6216;&#x51FD;&#x6570;&#x7684;&#x540D;' [AND ROUTINE_TYPE = {'PROCEDURE|FUNCTION'}];

存储函数

存储函数的创建与调用

不传入参数
#&#x65E0;&#x53C2;&#x6709;&#x8FD4;&#x56DE;
#1. &#x521B;&#x5EFA;&#x51FD;&#x6570;get_count(),&#x8FD4;&#x56DE;&#x516C;&#x53F8;&#x7684;&#x5458;&#x5DE5;&#x4E2A;&#x6570;
DELIMITER //
CREATE FUNCTION get_count() RETURNS INT
DETERMINISTIC
CONTAINS SQL

BEGIN
    RETURN (SELECT COUNT(1) FROM employees);
END //
DELIMITER ;

&#x8C03;&#x7528;&#x5B58;&#x50A8;&#x51FD;&#x6570;
SELECT get_count() FROM DUAL;
传入单个参数
#2. &#x521B;&#x5EFA;&#x51FD;&#x6570;ename_salary(),&#x6839;&#x636E;&#x5458;&#x5DE5;&#x59D3;&#x540D;&#xFF0C;&#x8FD4;&#x56DE;&#x5B83;&#x7684;&#x5DE5;&#x8D44;
DELIMITER $
CREATE FUNCTION ename_salary(input_name VARCHAR(25))  RETURNS DOUBLE(8,2)
    DETERMINISTIC
    CONTAINS SQL
BEGIN
    RETURN (SELECT salary FROM employees WHERE last_name = input_name);
END $
DELIMITER ;
drop FUNCTION ename_salary;

&#x8C03;&#x7528;
set @input_name = 'Austin';
SELECT ename_salary(@input_name);

#3. &#x521B;&#x5EFA;&#x51FD;&#x6570;dept_sal() ,&#x6839;&#x636E;&#x90E8;&#x95E8;&#x540D;&#xFF0C;&#x8FD4;&#x56DE;&#x8BE5;&#x90E8;&#x95E8;&#x7684;&#x5E73;&#x5747;&#x5DE5;&#x8D44;
DELIMITER $
CREATE FUNCTION dept_sal(dept_id INT) RETURNS INT
    DETERMINISTIC
    CONTAINS SQL
BEGIN
        RETURN (SELECT AVG(salary) FROM employees WHERE department_id =  dept_id);
END $
DELIMITER ;

&#x8C03;&#x7528;
SELECT dept_sal(60);
传入多个参数
#4. &#x521B;&#x5EFA;&#x51FD;&#x6570;add_float()&#xFF0C;&#x5B9E;&#x73B0;&#x4F20;&#x5165;&#x4E24;&#x4E2A;float&#xFF0C;&#x8FD4;&#x56DE;&#x4E8C;&#x8005;&#x4E4B;&#x548C;
DELIMITER $
CREATE FUNCTION add_float(f1 FLOAT, f2 FLOAT) RETURNS FLOAT
    DETERMINISTIC
    CONTAINS SQL
BEGIN
        RETURN (SELECT f1 + f2 FROM DUAL);
END $
DELIMITER ;

&#x8C03;&#x7528;
SELECT add_float(60, 60);

删除存储函数

DROP FUNCTION &#x5B58;&#x50A8;&#x51FD;&#x6570;&#x540D;;

查看存储函数的信息(3种)

SHOW CREATE FUNCTION &#x51FD;&#x6570;&#x8FC7;&#x7A0B;&#x540D;;

SHOW FUNCTION STATUS LIKE '&#x51FD;&#x6570;&#x8FC7;&#x7A0B;&#x540D;';

SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME='&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x6216;&#x51FD;&#x6570;&#x7684;&#x540D;' [AND ROUTINE_TYPE = {'PROCEDURE|FUNCTION'}];

存储过程与存储函数的参数作用

参数名 参数作用 LANGUAGE SQL 说明存储过程执行体是由SQL语句组成的,当前系统支持的语言为SQL。 [NOT] DETERMINISTIC 指明存储过程执行的结果是否确定。DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。NOT DETERMINISTIC表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为NOT DETERMINISTIC。 { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } 指明子程序使用SQL语句的限制。(下面有具体参数说明) SQL SECURITY { DEFINER | INVOKER } 执行当前存储过程的权限,即指明哪些用户能够执行当前存储过程。DEFINER:表示只有当前存储过程的创建者或者定义者才能执行当前存储过程。INVOKER :表示拥有当前存储过程的访问权限的用户能够执行当前存储过程

  • CONTAINS SQL表示当前存储过程的子程序包含SQL语句,但是并不包含读写数据的SQL语句;
  • NO SQL表示当前存储过程的子程序中不包含任何SQL语句;
  • READS SQL DATA表示当前存储过程的子程序中包含读数据的SQL语句;
  • MODIFIES SQL DATA表示当前存储过程的子程序中包含写数据的SQL语句。
  • 默认情况下,系统会指定为CONTAINS SQL。

报错:you might want to use the less safe log_bin_trust_function_creators variable

1. &#x52A0;&#x4E0A;&#x5FC5;&#x8981;&#x7684;&#x51FD;&#x6570;&#x7279;&#x6027;&#x201C;[NOT] DETERMINISTIC&#x201D;&#x548C;&#x201C;{CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}&#x201D;

2&#x3001; SET GLOBAL log_bin_trust_function_creators = 1;

错误处理

  • 咱们MYSQL执行的时候,如果出现报错,往往不仅有错误码CODE,还有个错误代号SQLSTATE,例如:其中的 1136就是错误码, 21S01就是错误代号SQLSTATE
    ERROR 1136 (21S01): Column count doesn't match value count at row 1

处理错误通常定义在存储过程和存储函数当中,使用如下:

错误的处理方式有3种
  • EXIT 遇到错误时就停止
  • CONTINUE 继续执行
  • UNDO 遇到错误时撤回之前的操作(MYSQL不支持)
处理错误的6种定义方式
    # &#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x540D;&#x79F0;
    DECLARE column_not_match CONDITION FOR 1130; # &#x901A;&#x8FC7;CODE &#x5B9A;&#x4E49;
    DECLARE column_not_match_2 CONDITION FOR SQLSTATE '21S01'; # &#x901A;&#x8FC7;SQLSTATE&#x5B9A;&#x4E49;

    # 1. &#x4F7F;&#x7528;&#x9519;&#x8BEF;&#x7801;
    DECLARE EXIT HANDLER FOR 1130 SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;,CODE 1130';

    # 2. &#x4F7F;&#x7528;&#x5B57;&#x7B26;&#x63D0;&#x793A;SQLSTATE
    DECLARE CONTINUE HANDLER FOR SQLSTATE '21S01' SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;, SQLSTATE 21S01';

    # 3. &#x4F7F;&#x7528;&#x5B9A;&#x4E49;&#x597D;&#x7684;&#x9519;&#x8BEF;&#x540D;&#x79F0;
    DECLARE EXIT HANDLER FOR column_not_match SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;,column_not_match';

    # 4. &#x5339;&#x914D;&#x6240;&#x6709;&#x4EE5;01&#x5F00;&#x5934;&#x7684;SQLSTATE&#x9519;&#x8BEF;&#x4EE3;&#x7801;&#xFF1B;
    DECLARE EXIT HANDLER FOR SQLWARNING SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;,SQLWARNING';

    # 5. &#x5339;&#x914D;&#x6240;&#x6709;&#x4EE5;02&#x5F00;&#x5934;&#x7684;SQLSTATE&#x9519;&#x8BEF;&#x4EE3;&#x7801;&#xFF1B;
    DECLARE EXIT HANDLER FOR NOT FOUND SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;,NOT FOUND';

    # 6. &#x5339;&#x914D;&#x6240;&#x6709;&#x6CA1;&#x6709;&#x88AB;SQLWARNING&#x6216;NOT FOUND&#x6355;&#x83B7;&#x7684;SQLSTATE&#x9519;&#x8BEF;&#x4EE3;&#x7801;&#xFF1B;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = '&#x8F93;&#x5165;&#x7684;&#x5B57;&#x6BB5;&#x4E0E;&#x5217;&#x5B57;&#x6BB5;&#x4E0D;&#x5339;&#x914D;,SQLEXCEPTION';

抛出一个自定义的错误
&#x793A;&#x4F8B;&#xFF1A;
SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x9519;&#x8BEF;';

存储过程、存储函数的区别

关键字 调用语法 返回值 应用场景 存储过程 PROCEDURE CALL 存储过程() 有0个或多个 一般用于更新 存储函数 FUNCTION SELECT 存储函数() 有且只能有一个 一般用于查询结果为一个值并返回时

注意:存储函数可以放在查询语句中使用,存储过程不行

系统变量与用户变量

系统变量

系统变量的分类

  • 全局系统变量(被所有会话所共享)
  • 会话系统变量(一个MYSQL的连接就相当于一个会话)
  • 注意:有一些系统变量,既是全局系统变量、也是会话系统变量

系统变量的查看、修改(全局、会话)

&#x5168;&#x5C40;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#x7684;&#x67E5;&#x770B;
SHOW GLOBAL VARIABLES;
SELECT @@global.character_set_database; # &#x67E5;&#x770B;&#x6307;&#x5B9A;&#x5168;&#x5C40;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;

&#x4F1A;&#x8BDD;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#x7684;&#x67E5;&#x770B;
SHOW SESSION VARIABLES;
SHOW VARIABLES; # &#x9ED8;&#x8BA4;&#x67E5;&#x770B;&#x4F1A;&#x8BDD;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;
SELECT @@session.character_set_database; # &#x67E5;&#x770B;&#x6307;&#x5B9A;&#x4F1A;&#x8BDD;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;

&#x4FEE;&#x6539;&#x5168;&#x5C40;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;
SET @@global.MAX_CONNECTIONS = 150;
SET global max_connections = 1000;

&#x4FEE;&#x6539;&#x4F1A;&#x8BDD;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;
SET @@session.character_set_database = 'gbk';
SET session character_set_database = 'utf8mb3';
  • 注意:要想让系统变量永久生效,只能通过更改配置文件的方式。否则重启MYSQL服务都会充值系统变量。MYSQL8修改全局系统变量时添加关键字PERSIST可以让全局系统变量持久化。例如:

SET PERSIST max_connections = 1000;

  • MySQL会将该命令的配置保存到数据目录下的 mysqld-auto.cnf 文件中,下次启动时会读取该文件,用其中的配置来覆盖默认的配置文件。

用户变量的创建、修改、使用(会话、局部)

会话用户变量
&#x4F1A;&#x8BDD;&#x7528;&#x6237;&#x53D8;&#x91CF;&#x7684;&#x5B9A;&#x4E49;
SET @A = 1;
SET @B = 2;
SET @SUM = @A + @B;

&#x4F1A;&#x8BDD;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#x7684;&#x4F7F;&#x7528;
SELECT @SUM FROM DUAL;
局部用户变量
  • 提示: 只能定义在存储过程或存储函数当中,准确来说是必须定义在 BEGIN END语句块当中,并且变量的声明必须放在BEGIN的首行。
DELIMITER $
CREATE PROCEDURE test_var()
BEGIN
        # 1. &#x58F0;&#x660E;&#x53D8;&#x91CF;
        DECLARE var1 INT DEFAULT 10;
        DECLARE var2 VARCHAR(12);
        DECLARE var3 DATE;

        # 2. &#x4E3A;&#x53D8;&#x91CF;&#x8D4B;&#x503C;
        # 2.1 &#x7B2C;&#x4E00;&#x79CD;&#x8D4B;&#x503C;&#x65B9;&#x5F0F;&#xFF0C;SET
        SET var2 = '&#x5F20;&#x4E09;';
        # 2.2 &#x7B2C;&#x4E8C;&#x79CD;&#x8D4B;&#x503C;&#x65B9;&#x5F0F;&#xFF0C;SELECT .. INTO ..
        SELECT STR_TO_DATE(NOW(),GET_FORMAT(DATETIME,'ISO')) INTO var3 FROM DUAL;

        # 3. &#x4F7F;&#x7528;&#x53D8;&#x91CF;
        SELECT var1,var2,var3;

END $
DELIMITER ;

流程控制

条件判断语句 IF、CASE

&#x6CE8;&#x610F;ELSE&#x540E;&#x9762;&#x4E0D;&#x9700;&#x8981;&#x63A5;THEN
DELIMITER $
CREATE PROCEDURE if_test(IN num INT)
BEGIN

    IF num = 0
         THEN SELECT 'the num is 0';
    ELSEIF num = 1
         THEN SELECT 'the num is 1';
    ELSE
         SELECT 'num&#x4E0D;&#x662F;0&#x4E5F;&#x4E0D;&#x662F;1&#x5457;';
    END IF;

END $
DELIMITER ;

CASE&#x7684;&#x7B2C;&#x4E00;&#x79CD;&#x7528;&#x6CD5;&#xFF0C;&#x76F8;&#x5F53;&#x4E8E;JAVA&#x4E2D;&#x7684;IF ELSE
DELIMITER $
CREATE PROCEDURE case_test(IN num INT)
BEGIN

    CASE   WHEN num = 0
        THEN SELECT 'the num is 0';
        WHEN num = 1
        THEN SELECT 'the num is 1';
    ELSE
        SELECT 'num&#x4E0D;&#x662F;0&#x4E5F;&#x4E0D;&#x662F;1&#x5457;';
    END CASE;

END $
DELIMITER ;

CASE&#x7684;&#x7B2C;&#x4E8C;&#x79CD;&#x7528;&#x6CD5;&#xFF0C;&#x76F8;&#x5F53;&#x4E8E;JAVA&#x4E2D;&#x7684;SWITCH
DELIMITER $
CREATE PROCEDURE case_test2(IN num INT)
BEGIN

 CASE   num WHEN 0
        THEN SELECT 'the num is 0';
        WHEN 1
        THEN SELECT 'the num is 1';
    ELSE
        SELECT 'num&#x4E0D;&#x662F;0&#x4E5F;&#x4E0D;&#x662F;1&#x5457;';
    END CASE;

END $
DELIMITER ;

循环语句LOOP、WHILE、REPEAT

LOOP 循环(需要配合LEAVE)

DELIMITER $
CREATE PROCEDURE loop_test(OUT result INT)
BEGIN
    # &#x521D;&#x59CB;&#x5316;
    DECLARE num INT DEFAULT 0;

    # &#x5FAA;&#x73AF;&#x6761;&#x4EF6;
    loop_lable:LOOP
        # &#x8FED;&#x4EE3;&#x6761;&#x4EF6;
        IF num = 10
            THEN LEAVE loop_lable;
        END IF;

    # &#x5FAA;&#x73AF;&#x4F53;&#x3001;&#x8FED;&#x4EE3;&#x6761;&#x4EF6;
    SET num = num + 1;

    END LOOP loop_lable;

    SET result = num;
END $
DELIMITER ;

&#x8C03;&#x7528;
CALL loop_test(@result);
SELECT @result;

WHILE循环

DELIMITER $
CREATE PROCEDURE while_test(OUT result INT)
BEGIN
        # &#x521D;&#x59CB;&#x5316;
        DECLARE num INT DEFAULT 0;
            # &#x5FAA;&#x73AF;&#x6761;&#x4EF6;
            WHILE num < 10 DO
                # &#x5FAA;&#x73AF;&#x4F53;&#x3001;&#x8FED;&#x4EE3;&#x6761;&#x4EF6;
                SET num = num + 1;
            END WHILE;

        SET result = num;
END $
DELIMITER ;

REPEAT循环(UNTIL后面不能加分号)

DELIMITER $
CREATE PROCEDURE repeat_test(OUT result INT)
BEGIN
        # &#x521D;&#x59CB;&#x5316;
        DECLARE num INT DEFAULT 0;

            # &#x5FAA;&#x73AF;&#x6761;&#x4EF6;
            REPEAT

                # &#x5FAA;&#x73AF;&#x4F53;&#x3001;&#x8FED;&#x4EE3;&#x6761;&#x4EF6;
                SET num = num + 1;

                UNTIL num > 10
            END REPEAT;

        SET result = num;
END $
DELIMITER ;

&#x8C03;&#x7528;
CALL repeat_test(@result);
SELECT @result;

跳转语句 LEAVE、ITERATE

  • 设置标签不仅仅可以作用在LOOP上,还可以作用到其他的循环结构、甚至是BEGIN上。一般都是配合LEAVE使用
  • ITERATE理解一下,与JAVA中的continue作用一样。

游标(相当于JAVA中的迭代器)

注意: 游标的查询结果集中的字段数,必须跟 INTO 后面的变量数一致

DELIMITER $
CREATE PROCEDURE cursor_test()
BEGIN
        # &#x5B9A;&#x4E49;&#x5C40;&#x90E8;&#x53D8;&#x91CF;
        DECLARE avg_sal DOUBLE DEFAULT 0.0;
        DECLARE avg_sum_sal DOUBLE DEFAULT 0.0;
        DECLARE count INT DEFAULT 1;

        # 1. &#x5B9A;&#x4E49;&#x6E38;&#x6807;
        DECLARE avg_sal_cursor CURSOR FOR
                SELECT AVG(salary) avg_sal
                FROM employees
                GROUP BY department_id
                ORDER BY avg_sal;

        # 2. &#x6253;&#x5F00;&#x6E38;&#x6807;
        OPEN avg_sal_cursor;

        # 3. &#x4F7F;&#x7528;&#x6E38;&#x6807;
        WHILE count <= 3 do # 每次都取出游标中的一条数据赋值给 avg_sal fetch avg_sal_cursor into avg_sal; 累计求和 set avg_sum_sal="avg_sum_sal" + 迭代条件 count="count" 1; end while; 4. 关闭游标 close avg_sal_cursor; select avg_sum_sal; $ delimiter ; 调用 call cursor_test(); < code></=>

触发器

基本语法

CREATE TRIGGER &#x89E6;&#x53D1;&#x5668;&#x540D;
(BEFORE|AFTER) (INSERT|DELETE|UPDATE) &#x8868;&#x540D;
FOR EACH ROW  # &#x8868;&#x793A;&#x8868;&#x4E2D;&#x7684;&#x6BCF;&#x4E00;&#x884C;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x65F6;&#x90FD;&#x4F1A;&#x89E6;&#x53D1;&#x8BE5;&#x89E6;&#x53D1;&#x5668;
BEGIN
    // &#x8FD9;&#x91CC;&#x5199;&#x65B9;&#x6CD5;&#x4F53;
    // &#x6CE8;&#x610F;&#xFF1A; &#x4F7F;&#x7528;NEW&#x53EF;&#x4EE5;&#x83B7;&#x53D6;&#x5230;&#x5F53;&#x524D;&#x64CD;&#x4F5C;&#x7684;&#x6570;&#x636E;
END

使用示例

DELIMITER //
CREATE TRIGGER after_insert_emp
AFTER INSERT ON test_tri
FOR EACH ROW
BEGIN
    INSERT INTO test_tri_log
    VALUES(NEW.last_name, NEW.salary);
END //

DELIMITER ;

查询触发器、删除触发器

&#x65B9;&#x5F0F;1
SHOW TRIGGERS;

&#x65B9;&#x5F0F;2
SHOW CREATE TRIGGER &#x89E6;&#x53D1;&#x5668;&#x540D;;

&#x65B9;&#x5F0F;3
SELECT * FROM information_schema.TRIGGERS;

&#x5220;&#x9664;&#x89E6;&#x53D1;&#x5668;
DROP TRIGGER IF EXISTS &#x89E6;&#x53D1;&#x5668;&#x540D;&#x79F0;;

触发器对于外键约束时的处理情况

  • 前提:触发器是对于从表进行定义的
  • 如果修改从表,那么触发器会正常执行
  • 如果 修改主表导致的从表内容修改,触发器不会执行。

常见问题

事物回滚的概念(MYSQL8.0保证了对DDL事物的原子性)

  • 原子性: 理解一次访问数据库的请求所执行的SQL,要么全都执行成功,要么全都别执行。
  • MYSQL中,DDL数据定义语言的操作都是不可回滚的,执行时需要务必注意
DDL&#x64CD;&#x4F5C;&#x56DE;&#x6EDA;&#x65E5;&#x5FD7;
&#x5199;&#x5165;&#x5230;data dictionary&#x6570;&#x636E;&#x5B57;&#x5178;&#x8868;mysql.innodb_ddl_log
&#xFF08;&#x8BE5;&#x8868;&#x662F;&#x9690;&#x85CF;&#x7684;&#x8868;&#xFF0C;&#x901A;&#x8FC7;show tables&#x65E0;&#x6CD5;&#x770B;&#x5230;&#xFF09;
  • DML操作如果想要回滚数据,则需要先将自动回滚关闭(建议关闭前先提交一次),而后手动提交事物

`
提交事物
commit;

将自动回滚设置为false
set autocommit = false;

执行DML操作

Original: https://www.cnblogs.com/itdqx/p/16578590.html
Author: code_Stars
Title: JAVA入门基础_从零开始的培训_MYSQL基础

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/594022/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 保存登录信息的Cookie加密技术

    所有需要账户登录的website 基本都会想到这样一个问题, 如何保持用户在一定时间内登录有效。 最近本人就在项目中遇到这样的需求,某些页面只能Admin账户登录后访问, 当登录A…

    Java 2023年6月5日
    083
  • 【校招VIP】[前端][二本][6分]简历一线校招通过率较低

    关注【校招VIP】 公众号,回复【简历】 ,添加校招顾问微信,即可获取简历指导! 本份简历是一位21届一本前端同学的简历,简历评分6分。 一、学员简历 二、指导意见 简历版式问题不…

    Java 2023年6月5日
    093
  • Mac APP store 更新页空白的解决办法

    如图,不知道什么时候起,我的 Mac APP store 的更新页面就变成了这样,即使有更新也依然显示空白。 试了几个网上搜到的方法,没效果,突然想到曾经看到有个工具可以在命令行进…

    Java 2023年6月5日
    0150
  • idea+spring boot+spring cloud+eureka+gateway整合

    1、创建一个maven项目 next Next Finish完成. 2、在创建好的maven项目上右键New->Module 选择Spring initializr创建eur…

    Java 2023年5月29日
    077
  • 设计模式 22 策略模式

    策略模式(Strategy Pattern)属于 行为型模式 生活中会面临很多抉择,每一个抉择会导向不同的结果,这时就会出现策略的选择。 程序中也是一样,而且更加复杂,生活中的抉择…

    Java 2023年6月6日
    076
  • Java_深度剖析ConcurrentHashMap

    本文基于Java 7的源码做剖析。 多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。虽然已经有一个…

    Java 2023年5月29日
    047
  • Spring ProtocolResolver接口

    Spring ProtocolResolver接口 ProtocolResolver是一个策略接口,可以用于自定义协议解析, 比如spring就有一个 “classpa…

    Java 2023年6月7日
    046
  • 自己动手实现一个简单的 IOC容器

    控制反转,即Inversion of Control(IoC),是面向对象中的一种设计原则,可以用有效降低架构代码的耦合度,从对象调用者角度又叫做依赖注入,即Dependency …

    Java 2023年6月9日
    080
  • RabbitMQ单机部署指南

    1.1.下载镜像 方式一:在线拉取 docker pull rabbitmq:3.8-management 方式二:从本地加载 上传到虚拟机中后,使用命令加载镜像即可: docke…

    Java 2023年6月7日
    067
  • Centos7.5离线安装Docker及容器运行报OCI runtime create failed 问题定位与解决

    前言 接上篇 《记一次centos挂载ceph存储的坑》 服务器重做了centos7.5版本的操作系统,剩下就是安装docker,考虑yum安装耗时较长,我一般都是直接安装二进制版…

    Java 2023年6月7日
    084
  • Java递归查找层级文件夹下特定内容的文件

    递归查找文件 引言 或许是文件太多,想找某个文件又忘记放哪了;又或者是项目改造,需要将外部调用接口进行改造,项目太多,又无法排查。那么怎么快速找到自己想要的内容就是一件值得思考的事…

    Java 2023年6月8日
    094
  • java的动态代理底层解析

    1.说明 代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。 2.类型: CGLib动态代理和JDK动态代理 3.使用介绍 (1…

    Java 2023年6月16日
    071
  • InnoDB学习(二)之ChangeBuffer

    ChangeBuffer是InnoDB缓存区的一种特殊的数据结构,当用户执行SQL对非唯一索引进行更改时,如果索引对应的数据页不在缓存中时,InnoDB不会直接加载磁盘数据到缓存数…

    Java 2023年6月8日
    072
  • 【game】1、pacman利用bfs进行搜索路径自动吃豆

    1.设计思路 设计思路有几个,一步步优化来的 v0.1 比较复杂,而且进行了2次bfs,浪费了大量时间 v0.2 简化了2次bfs的操作,但是有很多不必要的判断逻辑,并且考虑不够全…

    Java 2023年6月5日
    076
  • 狂神说Springcloud

    熟练使用SpringBoot 微服务快速开发框架 了解过Dubbo + Zookeeper 分布式基础 电脑配置内存不低于8G(我自己的是16G) 给大家看下多个服务跑起来后的内存…

    Java 2023年6月7日
    060
  • DM5加密的工具类

    代码: import org.springframework.security.crypto.password.PasswordEncoder; import java.math….

    Java 2023年6月13日
    064
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球