|
|
## 一、版本差异
|
|
|
|
|
|
| 差异 | 5.7 | 8.X | 备注 |
|
|
|
| -------- | --------------------- | ------------------------ | --- |
|
|
|
| 字符集 | utf8 | utf8mb4 | |
|
|
|
| 字符序 | utf8mb4_general_ci | utf8mb4_0900_ai_ci | |
|
|
|
| JDBC驱动名称 | com.mysql.jdbc.driver | com.mysql.cj.jdbc.driver | |
|
|
|
|
|
|
## 二、常用命令及SQL
|
|
|
+ 导出数据
|
|
|
```shell
|
|
|
1.整个库 (带gzip 压缩)
|
|
|
mysqldump -u 用户名 -p 数据库名 | gzip > 导出的文件名.sql.gz
|
|
|
2.指定表
|
|
|
mysqldump -u 用户名 -p 数据库名 表名1 表名2 > 导出的文件名.sql
|
|
|
3.只导出表结构
|
|
|
mysqldump -u 用户名 -p -d 数据库名 > 导出的文件名.sql
|
|
|
4.导出所有数据库
|
|
|
mysqldump -u 用户名 -p --all-databases > 导出的文件名.sql
|
|
|
```
|
|
|
`注意:在导出大型数据库时,建议使用--quick或--opt选项来避免将整个结果集装入内存`
|
|
|
|
|
|
+ 导入数据
|
|
|
```shell
|
|
|
1.导入整个数据库
|
|
|
mysql -u 用户名 -p 数据库名 < 导出的文件名.sql
|
|
|
2.导入指定表
|
|
|
mysql -u 用户名 -p 数据库名 < 导出的文件名.sql
|
|
|
3.在MySQL命令行中导入
|
|
|
mysql> use 数据库名;
|
|
|
mysql> source 导出的文件名.sql;
|
|
|
```
|
|
|
+ 查看表字段
|
|
|
```sql
|
|
|
desc table
|
|
|
show create table xxxx
|
|
|
```
|
|
|
## 三、常用函数
|
|
|
### 1.字符串
|
|
|
+ 连接
|
|
|
```sql
|
|
|
concat(字段1,符号,字段2)
|
|
|
```
|
|
|
+ 截取
|
|
|
```sql
|
|
|
SUBSTR(str, start, length):从字符串的start位置开始,截取length长度的一部分
|
|
|
LEFT(str, length):从字符串左边开始截取length个字符
|
|
|
RIGHT(str, length):从字符串右边开始截取length个字符
|
|
|
SUBSTRING(str, index):从字符串的index位置开始截取
|
|
|
```
|
|
|
+ 替换
|
|
|
```sql
|
|
|
REPLACE(str, from_str, to_str):将字符串中的from_str替换为to_str
|
|
|
```
|
|
|
+ 查找
|
|
|
```sql
|
|
|
FIND_IN_SET(search_string, string_list):在字符串列表中查找指定字符串的位置
|
|
|
select find_in_set('云-09-云NCK978','云-09-云NCK978,云-09-云NCK978') from dual;-- 返回1,下标从1开始
|
|
|
```
|
|
|
+ 大小写转换
|
|
|
```sql
|
|
|
UPPER(str):将字符串转换为大写
|
|
|
LOWER(str):将字符串转换为小写
|
|
|
```
|
|
|
+ 长度
|
|
|
```sql
|
|
|
LENGTH(str):获取字符串的长度
|
|
|
```
|
|
|
+ 去除空格
|
|
|
```sql
|
|
|
TRIM(str):去除字符串首尾的空格
|
|
|
LTRIM(str):去除字符串开始处的空格
|
|
|
RTRIM(str):去除字符串结尾处的空格
|
|
|
```
|
|
|
+ 列转行
|
|
|
```sql
|
|
|
group_concat(name separator ',') -- 逗号拼接
|
|
|
```
|
|
|
### 2.时间
|
|
|
+ 当前日期时间
|
|
|
```sql
|
|
|
now(): 返回当前日期和时间,格式为YYYY-MM-DD HH:MM:SS
|
|
|
current_timestamp(): 返回当前日期和时间戳
|
|
|
curtime(): 返回当前时间,格式为HH:MM:SS
|
|
|
|
|
|
```
|
|
|
+ 格式化
|
|
|
```sql
|
|
|
DATE_FORMAT(_date_, _format_) 将日期格式化为指定的格式。
|
|
|
TIME_FORMAT(_time_, _format_) 将时间格式化为指定的格式
|
|
|
```
|
|
|
+ 字符串转日期时间
|
|
|
```sql
|
|
|
select str_to_date('2014-04-22 15:47:06','%Y-%m-%d %H:%i:%s')
|
|
|
select str_to_date('20170615','%Y%m%d')
|
|
|
```
|
|
|
+ 日期时间加减
|
|
|
```sql
|
|
|
select date_add(curdate(),interval 1 day) -- 加1天
|
|
|
select date_add(curdate(),interval -1 day) -- 减1天
|
|
|
select date_add(now(),interval 1 hour) -- 加1小时
|
|
|
SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL 15 MINUTE) -- 加15分钟
|
|
|
```
|
|
|
+ 时间差计算
|
|
|
```sql
|
|
|
TIMESTAMPDIFF(MINUTE,时间1,时间2) -- 结果为分钟(支持年月日时分秒)
|
|
|
```
|
|
|
+ 其他
|
|
|
```sql
|
|
|
extract(unit FROM date): 从日期时间中提取年、月、日、时、分、秒等单元。
|
|
|
-- select extract(second from now())
|
|
|
week(date): 返回日期所在的周数。
|
|
|
weekday(date): 返回日期所在的星期几。
|
|
|
dayofweek(date): 返回日期是星期几(0-6,0为星期天)。
|
|
|
dayofmonth(date): 返回日期是月份中的第几天。
|
|
|
dayofyear(date): 返回日期是年份中的第几天。
|
|
|
monthname(date): 返回日期所在月份的名称。
|
|
|
dayname(date): 返回日期所在星期的名称。
|
|
|
```
|
|
|
### 3.数学
|
|
|
+ 向上取整
|
|
|
```sql
|
|
|
SELECT CEIL(3.3), CEILING(-3.3); -- 返回 4 和 -3
|
|
|
```
|
|
|
+ 向下取整
|
|
|
```sql
|
|
|
SELECT FLOOR(4.6), FLOOR(-4.6); -- 返回 4 和 -5
|
|
|
```
|
|
|
+ 随机数
|
|
|
```sql
|
|
|
SELECT RAND(), RAND(), RAND(1), RAND(1); -- 返回不同的随机数
|
|
|
```
|
|
|
+ 四舍五入
|
|
|
```sql
|
|
|
-- ROUND(X, [Y]) - 对数字 X 进行四舍五入,保留 Y 位小数。如果省略 Y,则返回整数
|
|
|
SELECT ROUND(10.5), ROUND(3.4, 1); -- 返回 10 和 3.4
|
|
|
```
|
|
|
### 4.判断
|
|
|
```sql
|
|
|
if(condition,'1','2') -- 如果condition不为Null,返回1,否则返回2
|
|
|
ifnull(f1,f2) -- 默认返回f1,如果f1为空返回f2
|
|
|
SELECT NVL(salary, 0) AS 收入 FROM employees; -- 如果salary 为null 返回0
|
|
|
```
|
|
|
### 5.类型转换
|
|
|
```sql
|
|
|
-- CAST: 用于转换数据类型。
|
|
|
SELECT CAST('123' AS UNSIGNED INTEGER); -- 将字符串转换为无符号整数
|
|
|
SELECT CAST(123 AS CHAR(3)); -- 将整数转换为固定长度的字符串
|
|
|
-- CONVERT: 用于转换数据类型,并在转换失败时返回NULL
|
|
|
SELECT CONVERT('123' TO UNSIGNED INTEGER); -- 将字符串转换为无符号整数
|
|
|
SELECT CONVERT(123 TO CHAR(3)); -- 将整数转换为固定长度的字符串
|
|
|
-- FORMAT: 用于将数值转换为字符串,并按照指定格式进行格式化
|
|
|
SELECT FORMAT(123.456, 2); -- 将浮点数格式化为保留两位小数的字符串
|
|
|
```
|
|
|
### 6.正则
|
|
|
```sql
|
|
|
-- 匹配 以prod结尾的表
|
|
|
SELECT * FROM information_schema.tables WHERE table_schema REGEXP 'prod$';
|
|
|
```
|
|
|
### 7.窗口函数
|
|
|
+ ROW_NUMBER() 为数据集中的每一行分配一个唯一的连续整数,通常用于排序
|
|
|
```sql
|
|
|
SELECT
|
|
|
name,
|
|
|
salary,
|
|
|
ROW_NUMBER() OVER (ORDER BY salary DESC) AS 'rank'
|
|
|
FROM
|
|
|
employees;
|
|
|
-- ROW_NUMBER()函数根据salary列降序排序,并为每行分配一个排名。
|
|
|
```
|
|
|
+ RANK() 类似于ROW_NUMBER(),但它会在有重复值时给出相同的排名
|
|
|
```sql
|
|
|
SELECT
|
|
|
name,
|
|
|
salary,
|
|
|
RANK() OVER (ORDER BY salary DESC) AS 'rank'
|
|
|
FROM
|
|
|
employees;
|
|
|
```
|
|
|
+ DENSE_RANK() 函数在排名时不会跳过排名,即使有重复值
|
|
|
```sql
|
|
|
SELECT
|
|
|
name,
|
|
|
salary,
|
|
|
DENSE_RANK() OVER (ORDER BY salary DESC) AS 'rank'
|
|
|
FROM
|
|
|
employees;
|
|
|
```
|
|
|
+ LEAD() 和 LAG() 访问当前行之后或之前的行的数据
|
|
|
```sql
|
|
|
SELECT
|
|
|
name,
|
|
|
salary,
|
|
|
LAG(salary, 1) OVER (ORDER BY salary DESC) AS 'previous_salary',
|
|
|
LEAD(salary, 1) OVER (ORDER BY salary DESC) AS 'next_salary'
|
|
|
FROM
|
|
|
employees;
|
|
|
```
|
|
|
+ SUM()、AVG()、MIN()、MAX() 会对排序后的数据集的子集进行计算
|
|
|
```sql
|
|
|
SELECT
|
|
|
name,
|
|
|
salary,
|
|
|
SUM(salary) OVER (ORDER BY salary DESC) AS 'running_total'
|
|
|
FROM
|
|
|
employees;
|
|
|
```
|
|
|
|
|
|
示例:
|
|
|
原始数据
|
|
|
![[Pasted image 20240108170944.png]]
|
|
|
+ 排名
|
|
|
```sql
|
|
|
-- 1.科目分数排名
|
|
|
select stu_no,course,score,row_number() over (partition by course order by score desc) from tb_score;
|
|
|
-- rank会出先相同排名,如果2个并列的第1之后,下一个我想是第3名,则可以使用RANK函数实现
|
|
|
select stu_no,course,score,rank() over (partition by course order by score desc) from tb_score;
|
|
|
--
|
|
|
select stu_no,course,score,dense_rank() over (partition by course order by score desc) from tb_score
|
|
|
```
|
|
|
+ 排名+分组 NTILE()
|
|
|
```sql
|
|
|
-- NTILE函数的作用是对每个分组排名后,再将对应分组分成N个小组
|
|
|
select stu_no,course,score,rank() over (partition by course order by score desc) rn,NTILE(4) over(partition by course order by score desc ) rn_group from tb_score
|
|
|
```
|
|
|
+ 取出每组第一名学号 first_value()
|
|
|
```sql
|
|
|
select stu_no,course,score,first_value(stu_no) over (partition by course order by score desc),rank() over (partition by course order by score desc) from tb_score
|
|
|
```
|
|
|
+ 累加 sum函数对score做累加计算,根据course分组后计算出每组的累加值
|
|
|
```sql
|
|
|
select stu_no,course,score,sum(score) over (partition by course order by score desc) from tb_score;
|
|
|
-- 直接展示累加结果 增加 rows between unbounded preceding and unbounded following
|
|
|
select stu_no,course,score,sum(score) over (partition by course order by score desc rows between unbounded preceding and unbounded following) from tb_score
|
|
|
```
|
|
|
## 四、常用SQL
|
|
|
+ 按时间范围统计,(年月周天)
|
|
|
```sql
|
|
|
select count(YEAR(a.io_first) = YEAR(CURDATE()) and MONTH(a.io_first) = MONTH(CURDATE()) and
|
|
|
DAY(a.io_first) = DAY(CURDATE()) or null) as 'today', count(YEAR(a.io_first) = YEAR(CURDATE()) and WEEK(a.io_first) = WEEK(CURDATE()) or null) as 'week', count(YEAR(a.io_first) = YEAR(CURDATE()) and MONTH(a.io_first) = MONTH(CURDATE()) or null) as 'month', count(YEAR(a.io_first) = YEAR(CURDATE()) or null) as 'year'from ar_t_vehicle_io a
|
|
|
```
|
|
|
+ 时间范围
|
|
|
```sql
|
|
|
-- 今天
|
|
|
YEAR(a.io_first) = YEAR(CURDATE()) and MONTH(a.io_first) = MONTH(CURDATE()) and DAY(a.io_first)
|
|
|
= DAY(CURDATE())
|
|
|
-- 本周
|
|
|
YEAR(a.io_first) = YEAR(CURDATE()) and WEEK(a.io_first) = WEEK(CURDATE())
|
|
|
-- 本月
|
|
|
YEAR(a.io_first) = YEAR(CURDATE()) and MONTH(a.io_first) = MONTH(CURDATE())
|
|
|
-- 本年
|
|
|
YEAR(a.io_first) = YEAR(CURDATE())
|
|
|
```
|
|
|
## 五、索引
|
|
|
|
|
|
MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索等。
|
|
|
- 从 `功能逻辑` 上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。
|
|
|
- 按照 `物理实现方式` ,索引可以分为 2 种:聚簇索引和非聚簇索引。
|
|
|
- 按照 `作用字段个数进行划分`,分成单列索引和联合索引。
|
|
|
### 5.1 普通索引
|
|
|
在创建普通索引时,不附加任何限制条件,只是用于提高查询效率。这类索引可以创建在`任何数据类型`中,其值 是否唯一和非空,要由字段本身的完整性约束条件决定
|
|
|
### 5.2 唯一索引
|
|
|
在创建唯一性索引时,限制该索引的值必须是唯一的,但允许有 空值。在一张数据表里`可以有多个唯一索引`
|
|
|
### 5.3 主键索引
|
|
|
默认主键,一张表里`最多只有一个主键索引`,不允许重复、空值
|
|
|
### 5.4 全文索引
|
|
|
全文索引(也称全文检索)是目前`搜索引擎`使用的一种关键技术。它能够利用【`分词技术`】等多种算法智能分析 出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。全文索引非 常适合大型数据集,对于小的数据集,它的用处比较小。全文索引只能创建在`CHAR、VARCHAR或TEXT`类型及其系列类型的字段上,`查询数据量较大的 字符串类型`的字段时,使用全文索引可以提高查询速度。
|
|
|
|
|
|
全文索引典型的有两种类型:自然语言的全文索引和布尔全文索引
|
|
|
### 5.5 空间索引
|
|
|
|
|
|
## 六、事务
|
|
|
|
|
|
## 七、维护
|
|
|
+ 当前在执行SQL
|
|
|
```sql
|
|
|
SHOW PROCESSLIST;
|
|
|
```
|
|
|
+ 慢SQL
|
|
|
```sql
|
|
|
-- 如果慢查询日志被启用,可以查看日志文件来获取 SQL 语句
|
|
|
SHOW VARIABLES LIKE 'slow_query_log';
|
|
|
```
|
|
|
+ 当前事务和锁
|
|
|
```sql
|
|
|
-- 确认有没有锁等待:
|
|
|
show status like 'innodb_row_lock%';
|
|
|
select * from information_schema.innodb_trx;
|
|
|
```
|
|
|
## 八、其他
|
|
|
### 8.1 全文检索
|
|
|
### 8.2 GIS
|
|
|
### 8.3 JSON
|
|
|
|
|
|
|
|
|
## 九、常见问题
|
|
|
|
|
|
### 9.1 字符集
|
|
|
utf8mb4_general_ci 和 utf8mb4_0900_ai_ci 不兼容,关联查询报错,需要保持一致。
|
|
|
### 9.2 concat
|
|
|
其中一个为Null,结果为Null,需要加ifnull 判断,或者使用concat_ws
|
|
|
```sql
|
|
|
concat(a.io_first,'--',a.io_last)
|
|
|
-- 修改
|
|
|
ifnull(concat(a.io_first,'--',a.io_last),a.io_first)
|
|
|
``` |