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.

330 lines
12 KiB

## 一、版本差异
| 差异 | 5.7 | 8.X | 备注 |
| -------- | --------------------- | ------------------------ | --- |
| 字符集 | utf8 | utf8mb4 | |
| 字符序 | utf8mb4_general_ci | utf8mb4_0900_ai_ci | |
| JDBC驱动名称 | com.mysql.jdbc.driver | com.mysql.cj.jdbc.driver | |
2 months ago
| | | | |
2 years ago
## 二、常用命令及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;
```
2 years ago
+ 查看表字段
```sql
desc table
show create table xxxx
```
8 months ago
+ 查看表占用情况
```sql
-- 查看表的数据大小
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.字符串
+ 连接
```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-60为星期天
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
2 years ago
### 8.3 JSON
2 years ago
## 九、常见问题
### 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)
8 months ago
```
### 9.3 删除数据后空间未释放
| | INNODB | MyISAM |
| ----------------------- | ------ | ------ |
| drop table | 立即释放 | 立即释放 |
| truncate table | 立即释放 | 立即释放 |
| delete from table | 不释放 | 立即释放 |
| delete from table where | 不释放 | 不释放 |
如果innodb引擎使用delete语句想要立即释放空间需要执行
```sql
optimize table 表名;
```