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
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 | |
二、常用命令及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-6,0为星期天)。
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;
- 排名
-- 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 表名;