You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

一、版本差异

差异 5.7 8.X 备注
字符集 utf8 utf8mb4
字符序 utf8mb4_general_ci utf8mb4_0900_ai_ci
JDBC驱动名称 com.mysql.jdbc.driver com.mysql.cj.jdbc.driver

二、常用命令及SQL

  • 导出数据
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选项来避免将整个结果集装入内存

  • 导入数据
1.导入整个数据库
mysql -u 用户名 -p 数据库名 < 导出的文件名.sql
2.导入指定表
mysql -u 用户名 -p 数据库名 < 导出的文件名.sql
3.在MySQL命令行中导入
mysql> use 数据库名;
mysql> source 导出的文件名.sql;
  • 查看表字段
desc table
show create table xxxx
  • 查看表占用情况
-- 查看表的数据大小
SELECT
    table_schema AS '数据库名', 
    table_name AS '表名',
    round(((data_length) / 1024 / 1024), 2) AS '数据大小(MB)',
    round(sum(index_length) / 1024 / 1024, 2) AS '索引大小(MB)' 
FROM information_schema.TABLES 
WHERE table_schema = '您的数据库名'; -- 替换为您的数据库名

三、常用函数

1.字符串

  • 连接
concat(字段1,符号,字段2)
  • 截取
SUBSTR(str, start, length):从字符串的start位置开始,截取length长度的一部分
LEFT(str, length):从字符串左边开始截取length个字符
RIGHT(str, length):从字符串右边开始截取length个字符
SUBSTRING(str, index):从字符串的index位置开始截取
  • 替换
REPLACE(str, from_str, to_str):将字符串中的from_str替换为to_str
  • 查找
FIND_IN_SET(search_string, string_list):在字符串列表中查找指定字符串的位置
select find_in_set('云-09-云NCK978','云-09-云NCK978,云-09-云NCK978') from dual;-- 返回1,下标从1开始
  • 大小写转换
UPPER(str):将字符串转换为大写
LOWER(str):将字符串转换为小写
  • 长度
LENGTH(str):获取字符串的长度
  • 去除空格
TRIM(str):去除字符串首尾的空格
LTRIM(str):去除字符串开始处的空格
RTRIM(str):去除字符串结尾处的空格
  • 列转行
group_concat(name separator ',') -- 逗号拼接

2.时间

  • 当前日期时间
now(): 返回当前日期和时间,格式为YYYY-MM-DD HH:MM:SS
current_timestamp(): 返回当前日期和时间戳
curtime(): 返回当前时间,格式为HH:MM:SS

  • 格式化
DATE_FORMAT(_date_, _format_) 将日期格式化为指定的格式。
TIME_FORMAT(_time_, _format_) 将时间格式化为指定的格式
  • 字符串转日期时间
select str_to_date('2014-04-22 15:47:06','%Y-%m-%d %H:%i:%s')
select str_to_date('20170615','%Y%m%d')
  • 日期时间加减
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分钟
  • 时间差计算
TIMESTAMPDIFF(MINUTE,时间1,时间2) -- 结果为分钟(支持年月日时分秒)
  • 其他
extract(unit FROM date): 从日期时间中提取年、月、日、时、分、秒等单元。
-- select extract(second from now())
week(date): 返回日期所在的周数。
weekday(date): 返回日期所在的星期几。
dayofweek(date): 返回日期是星期几(0-60为星期天)。
dayofmonth(date): 返回日期是月份中的第几天。
dayofyear(date): 返回日期是年份中的第几天。
monthname(date): 返回日期所在月份的名称。
dayname(date): 返回日期所在星期的名称。

3.数学

  • 向上取整
SELECT CEIL(3.3), CEILING(-3.3); -- 返回 4 和 -3
  • 向下取整
SELECT FLOOR(4.6), FLOOR(-4.6); -- 返回 4 和 -5
  • 随机数
SELECT RAND(), RAND(), RAND(1), RAND(1); -- 返回不同的随机数
  • 四舍五入
-- ROUND(X, [Y]) - 对数字 X 进行四舍五入,保留 Y 位小数。如果省略 Y则返回整数
SELECT ROUND(10.5), ROUND(3.4, 1); -- 返回 10 和 3.4

4.判断

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.类型转换

-- 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.正则

-- 匹配 以prod结尾的表
SELECT * FROM information_schema.tables WHERE table_schema REGEXP 'prod$';

7.窗口函数

  • ROW_NUMBER() 为数据集中的每一行分配一个唯一的连续整数,通常用于排序
SELECT
  name,
  salary,
  ROW_NUMBER() OVER (ORDER BY salary DESC) AS 'rank'
FROM
  employees;
-- ROW_NUMBER()函数根据salary列降序排序并为每行分配一个排名。
  • RANK() 类似于ROW_NUMBER(),但它会在有重复值时给出相同的排名
SELECT
  name,
  salary,
  RANK() OVER (ORDER BY salary DESC) AS 'rank'
FROM
  employees;
  • DENSE_RANK() 函数在排名时不会跳过排名,即使有重复值
SELECT
  name,
  salary,
  DENSE_RANK() OVER (ORDER BY salary DESC) AS 'rank'
FROM
  employees;
  • LEAD() 和 LAG() 访问当前行之后或之前的行的数据
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() 会对排序后的数据集的子集进行计算
SELECT
  name,
  salary,
  SUM(salary) OVER (ORDER BY salary DESC) AS 'running_total'
FROM
  employees;

示例: 原始数据 !Pasted image 20240108170944.png

  • 排名
-- 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()
-- 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()
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分组后计算出每组的累加值
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

  • 按时间范围统计,(年月周天)
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
  • 时间范围
-- 今天  
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
SHOW PROCESSLIST;
  • 慢SQL
-- 如果慢查询日志被启用,可以查看日志文件来获取 SQL 语句
SHOW VARIABLES LIKE 'slow_query_log';
  • 当前事务和锁
-- 确认有没有锁等待: 
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

concat(a.io_first,'--',a.io_last)
-- 修改
ifnull(concat(a.io_first,'--',a.io_last),a.io_first)

9.3 删除数据后空间未释放

INNODB MyISAM
drop table 立即释放 立即释放
truncate table 立即释放 立即释放
delete from table 不释放 立即释放
delete from table where 不释放 不释放
如果innodb引擎使用delete语句想要立即释放空间需要执行
optimize table 表名;