diff --git a/work常用/mysql 常用.md b/work常用/mysql 常用.md index 2ca484d..f3d0661 100644 --- a/work常用/mysql 常用.md +++ b/work常用/mysql 常用.md @@ -1 +1,289 @@ -+ \ No newline at end of file +## 一、版本差异 + +| 差异 | 5.7 | 8.X | 备注 | +| ---- | ---- | ---- | ---- | +| 字符集 | utf8 | utf8mb4 | | +| 字符序 | utf8mb4_general_ci | utf8mb4_0900_ai_ci | | +| JDBC驱动名称 | com.mysql.jdbc.driver | com.mysql.cj.jdbc.driver | | + +## 二、常用命令 ++ 导出数据 +```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; +``` + +## 三、常用函数 +### 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 \ No newline at end of file