MySQL8.0新特性

news2024/11/23 7:42:25

1、新增降序索引

MySQL 5.7:在语法上支持降序索引,但实际上创建的仍然是升序索引

MySQL 8.0:真正支持降序索引(只有Innodb存储引擎支持降序索引)

# ====MySQL 5.7演示====
mysql> create table t1(c1 int,c2 int,index idx_c1_c2(c1,c2 desc));
Query OK, 0 rows affected (0.04 sec)

mysql> insert into t1 (c1,c2) values(1, 10),(2,50),(3,50),(4,100),(5,80);
Query OK, 5 rows affected (0.02 sec)

mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL,
  `c2` int(11) DEFAULT NULL,
  KEY `idx_c1_c2` (`c1`,`c2`)    --注意这里,c2字段是升序
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> explain select * from t1 order by c1,c2 desc;  --5.7也会使用索引,但是Extra字段里有filesort文件排序
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | t1    | NULL       | index | NULL          | idx_c1_c2 | 10      | NULL |    1 |   100.00 | Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.01 sec)
# ====MySQL 8.0演示====
mysql> create table t1(c1 int,c2 int,index idx_c1_c2(c1,c2 desc));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1 (c1,c2) values(1, 10),(2,50),(3,50),(4,100),(5,80);
Query OK, 5 rows affected (0.02 sec)

mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int DEFAULT NULL,
  `c2` int DEFAULT NULL,
  KEY `idx_c1_c2` (`c1`,`c2` DESC)  --降序索引是生效的
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql> explain select * from t1 order by c1,c2 desc;  --Extra字段里没有filesort文件排序,充分利用了降序索引
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | index | NULL          | idx_c1_c2 | 10      | NULL |    1 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t1 order by c1 desc,c2;  --Extra字段里有Backward index scan,意思是反向扫描索引;
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                            |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+
|  1 | SIMPLE      | t1    | NULL       | index | NULL          | idx_c1_c2 | 10      | NULL |    1 |   100.00 | Backward index scan; Using index |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t1 order by c1 desc,c2 desc;  --Extra字段里有filesort文件排序,排序必须按照每个字段定义的排序或按相反顺序才能充分利用索引
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | t1    | NULL       | index | NULL          | idx_c1_c2 | 10      | NULL |    1 |   100.00 | Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

2、group by 不再隐式排序

MySQL 5.7:对于 group by 字段会排序

MySQL 8.0:对于 group by 字段不再隐式排序,如需要排序,必须显式加上order by 子句

# ====MySQL 5.7演示====
mysql> select count(*),c2 from t1 group by c2;
+----------+------+
| count(*) | c2   |
+----------+------+
|        1 |   10 |
|        2 |   50 |
|        1 |   80 |
|        1 |  100 |
+----------+------+
4 rows in set (0.00 sec)
# ====MySQL 8.0演示====
mysql> select count(*),c2 from t1 group by c2;   --8.0版本group by不再默认排序
+----------+------+
| count(*) | c2   |
+----------+------+
|        1 |   10 |
|        2 |   50 |
|        1 |  100 |
|        1 |   80 |
+----------+------+
4 rows in set (0.00 sec)

mysql> select count(*),c2 from t1 group by c2 order by c2;  --8.0版本group by不再默认排序,需要自己加order by
+----------+------+
| count(*) | c2   |
+----------+------+
|        1 |   10 |
|        2 |   50 |
|        1 |   80 |
|        1 |  100 |
+----------+------+
4 rows in set (0.00 sec)

3、增加隐藏索引

MySQL 8.0:

  1. 使用 invisible 关键字在创建表或者进行表变更中设置索引为隐藏索引(注意:主键不能设置为 invisible)
  2. 隐藏索引只是对于业务是不可见的,Mysql后台还是会维护这个索引。因为在查询时优化器不会使用该索引,即使使用force index,优化器也不会使用该索引,同时也不会报索引不存在的错误,因为索引仍然真实存在
  3. 需要时,可以把隐藏索引快速恢复成可见
  4. 软删除就可以使用隐藏索引,比如我们觉得某个索引没用了,但是担心删除后这个索引在某些时候还是有用的。于是又得把这个索引加回来,那如果表数据量很大的话,这种操作是很耗时的,成本较高。这时,我们可以将索引先设置为隐藏索引,等到真的确认索引没用了再删除。
# 创建t2表,里面的c2字段为隐藏索引
mysql> create table t2(c1 int, c2 int, index idx_c1(c1), index idx_c2(c2) invisible);
Query OK, 0 rows affected (0.02 sec)

mysql> show index from t2\G
*************************** 1. row ***************************
        Table: t2
   Non_unique: 1
     Key_name: idx_c1
 Seq_in_index: 1
  Column_name: c1
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES --idx_c1索引可见
   Expression: NULL
*************************** 2. row ***************************
        Table: t2
   Non_unique: 1
     Key_name: idx_c2
 Seq_in_index: 1
  Column_name: c2
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: NO   --idx_c2索引被隐藏
   Expression: NULL
2 rows in set (0.00 sec)

mysql> explain select * from t2 where c1=1;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t2    | NULL       | ref  | idx_c1        | idx_c1 | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t2 where c2=1;  --idx_c2索引不会被使用
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
# 如果想测试隐藏索引,可以在会话级别下,打开开关,在查询时优化器可以使用Mysql的隐藏索引
mysql> select @@optimizer_switch\G   --查看各种参数
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on
1 row in set (0.00 sec)

mysql> set session optimizer_switch="use_invisible_indexes=on";  ----在会话级别设置查询优化器可以看到隐藏索引
Query OK, 0 rows affected (0.00 sec)

mysql> select @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=on,skip_scan=on,hash_join=on
1 row in set (0.00 sec)

mysql> explain select * from t2 where c2=1;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t2    | NULL       | ref  | idx_c2        | idx_c2 | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

# 测试完毕,觉得隐藏索引可以使用,再修改成可见的
mysql> alter table t2 alter index idx_c2 visible;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

4、新增函数索引

MySQL 5.7:函数作用在索引字段上,会使索引失效

MySQL 8.0:引入函数索引,支持在索引中使用函数。函数索引基于虚拟列功能实现,在MySQL中相当于新增了一个列,这个列会根据你的函数来进行计算结果,然后使用函数索引的时候就会用这个计算后的列作为索引

mysql> create table t3(c1 varchar(10),c2 varchar(10));
Query OK, 0 rows affected (0.02 sec)

mysql> create index idx_c1 on t3(c1);     --创建普通索引
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> create index func_idx on t3((UPPER(c2)));  --创建一个大写的函数索引
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from t3\G
*************************** 1. row ***************************
        Table: t3
   Non_unique: 1
     Key_name: idx_c1
 Seq_in_index: 1
  Column_name: c1
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: NULL
*************************** 2. row ***************************
        Table: t3
   Non_unique: 1
     Key_name: func_idx
 Seq_in_index: 1
  Column_name: NULL
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: upper(`c2`)    --函数表达式
2 rows in set (0.00 sec)

mysql> explain select * from t3 where upper(c1)='ZHUGE'; -- 普通索引没有使用到
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t3    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t3 where upper(c2)='ZHUGE';  --使用了函数索引
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | t3    | NULL       | ref  | func_idx      | func_idx | 43      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

5、innodb存储引擎select for update跳过锁等待

MySQL 5.7:select…for update,如果获取不到锁,会一直等待,直到innodb_lock_wait_timeout超时

MySQL 8.0:select … for share(8.0新增加查询共享锁的语法) 或 select … for update,可以跳过锁等待,或者跳过锁定

    1. 通过添加 nowait 语法,查询会报错立即返回,不等待锁,提高系统性能
    2. 通过添加 skip locked 语法,也会立即返回,区别是不会报错,并且返回不包含被锁定的行的结果集,提高系统性能(比如购票场景,返回没有被锁定的座位)
# session1:
mysql> select * from t1;
+------+------+
| c1   | c2   |
+------+------+
|    1 |   10 |
|    2 |   50 |
|    3 |   50 |
|    4 |  100 |
|    5 |   80 |
+------+------+
5 rows in set (0.00 sec)
    
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update t1 set c2 = 60 where c1 = 2;     --锁定第二条记录
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0


# session2:    
mysql> select * from t1 where c1 = 2 for update;   --等待超时
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> select * from t1 where c1 = 2 for update nowait;   --查询立即返回
ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.

mysql> select * from t1 for update skip locked;  --查询立即返回,过滤掉了第二行记录
+------+------+
| c1   | c2   |
+------+------+
|    1 |   10 |
|    3 |   50 |
|    4 |  100 |
|    5 |   80 |
+------+------+
4 rows in set (0.00 sec)

6、新增innodb_dedicated_server自适应参数

MySQL 8.0:InnoDB会根据服务器上检测到的内存大小自动调整 innodb_buffer_pool_size,innodb_log_file_size 等参数,尽可能的冲分利用系统资源

默认是关闭的,不建议开启该参数,因为如果服务器不是专用来给MySQL数据库的,不然会影响其它程序

mysql> show variables like '%innodb_dedicated_server%';   --默认是OFF关闭,修改为ON打开
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| innodb_dedicated_server | OFF   |
+-------------------------+-------+
1 row in set (0.02 sec)

7、死锁检查控制

MySQL 8.0:增加动态变量 innodb_deadlock_detect,用于控制系统是否执行 InnoDB 死锁检查,默认是打开的。

死锁检测会耗费数据库性能的,对于高并发的系统,可以关闭该功能,提高系统性能。前提是要确保系统极少情况会发生死锁,同时要将锁等待超时参数调小一点,以防出现死锁等待过久的情况

mysql> show variables like '%innodb_deadlock_detect%';  --默认是打开的
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_deadlock_detect | ON    |
+------------------------+-------+
1 row in set, 1 warning (0.01 sec)

8、undo文件不再使用系统表空间

MySQL 5.7:默认创建ib开头的系统表空间

MySQL 8.0:默认创建2个UNDO表空间,不再使用系统表空间
在这里插入图片描述

9、 binlog日志过期时间精确到秒

MySQL 5.7:设置expire_logs_days参数,只能精确到天

MySQL 8.0:参数名称发生变化,设置binlog_expire_logs_seconds参数,并且可以精确到秒

10、窗口函数(Window Functions):也称分析函数

MySQL 8.0:

  1. 新增窗口函数的概念,在聚合函数( SUM、COUNT )后面加上over()就变成窗口函数,在over括号里可以加上partition by等分组关键字指定如何分组
  2. 窗口函数即便分组也不会将多行查询结果合并为一行,而是将结果放回多行当中
# 创建一张账户余额表
CREATE TABLE `account_channel` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
  `channel` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '账户渠道',
  `balance` int DEFAULT NULL COMMENT '余额',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

# 插入一些示例数据
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('1', 'zhuge', 'wx', '100');
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('2', 'zhuge', 'alipay', '200');
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('3', 'zhuge', 'yinhang', '300');
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('4', 'lilei', 'wx', '200');
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('5', 'lilei', 'alipay', '100');
INSERT INTO `test`.`account_channel` (`id`, `name`, `channel`, `balance`) VALUES ('6', 'hanmeimei', 'wx', '500');

mysql> select * from account_channel;
+----+-----------+---------+---------+
| id | name      | channel | balance |
+----+-----------+---------+---------+
|  1 | zhuge     | wx      |     100 |
|  2 | zhuge     | alipay  |     200 |
|  3 | zhuge     | yinhang |     300 |
|  4 | lilei     | wx      |     200 |
|  5 | lilei     | alipay  |     100 |
|  6 | hanmeimei | wx      |     500 |
+----+-----------+---------+---------+
6 rows in set (0.00 sec)

mysql> select name,sum(balance) from account_channel group by name;
+-----------+--------------+
| name      | sum(balance) |
+-----------+--------------+
| zhuge     |          600 |
| lilei     |          300 |
| hanmeimei |          500 |
+-----------+--------------+
3 rows in set (0.00 sec)

# sum(balance) over(partition by name) 窗口函数
mysql> select name,channel,balance,sum(balance) over(partition by name) as sum_balance from account_channel;
+-----------+---------+---------+-------------+
| name      | channel | balance | sum_balance |
+-----------+---------+---------+-------------+
| hanmeimei | wx      |     500 |         500 |
| lilei     | wx      |     200 |         300 |
| lilei     | alipay  |     100 |         300 |
| zhuge     | wx      |     100 |         600 |
| zhuge     | alipay  |     200 |         600 |
| zhuge     | yinhang |     300 |         600 |
+-----------+---------+---------+-------------+
6 rows in set (0.00 sec)

mysql> select name,channel,balance,sum(balance) over(partition by name order by balance) as sum_balance from account_channel;
+-----------+---------+---------+-------------+
| name      | channel | balance | sum_balance |
+-----------+---------+---------+-------------+
| hanmeimei | wx      |     500 |         500 |
| lilei     | alipay  |     100 |         100 |
| lilei     | wx      |     200 |         300 |
| zhuge     | wx      |     100 |         100 |
| zhuge     | alipay  |     200 |         300 |
| zhuge     | yinhang |     300 |         600 |
+-----------+---------+---------+-------------+
6 rows in set (0.00 sec)


# over()里如果不加条件,则会使用Where条件所有行
mysql> select name,channel,balance,sum(balance) over() as sum_balance from account_channel;
+-----------+---------+---------+-------------+
| name      | channel | balance | sum_balance |
+-----------+---------+---------+-------------+
| zhuge     | wx      |     100 |        1400 |
| zhuge     | alipay  |     200 |        1400 |
| zhuge     | yinhang |     300 |        1400 |
| lilei     | wx      |     200 |        1400 |
| lilei     | alipay  |     100 |        1400 |
| hanmeimei | wx      |     500 |        1400 |
+-----------+---------+---------+-------------+
6 rows in set (0.00 sec)

mysql> select name,channel,balance,avg(balance) over(partition by name) as avg_balance from account_channel;
+-----------+---------+---------+-------------+
| name      | channel | balance | avg_balance |
+-----------+---------+---------+-------------+
| hanmeimei | wx      |     500 |    500.0000 |
| lilei     | wx      |     200 |    150.0000 |
| lilei     | alipay  |     100 |    150.0000 |
| zhuge     | wx      |     100 |    200.0000 |
| zhuge     | alipay  |     200 |    200.0000 |
| zhuge     | yinhang |     300 |    200.0000 |
+-----------+---------+---------+-------------+
6 rows in set (0.00 sec)

专用窗口函数:

  • 序号函数:ROW_NUMBER()、RANK()、DENSE_RANK()
  • 分布函数:PERCENT_RANK()、CUME_DIST()
  • 前后函数:LAG()、LEAD()
  • 头尾函数:FIRST_VALUE()、LAST_VALUE()
  • 其它函数:NTH_VALUE()、NTILE()
# 按照balance字段排序,展示序号
mysql> select name,channel,balance,row_number() over(order by balance) as row_number1 from account_channel;
+-----------+---------+---------+-------------+
| name      | channel | balance | row_number1 |
+-----------+---------+---------+-------------+
| zhuge     | wx      |     100 |           1 |
| lilei     | alipay  |     100 |           2 |
| zhuge     | alipay  |     200 |           3 |
| lilei     | wx      |     200 |           4 |
| zhuge     | yinhang |     300 |           5 |
| hanmeimei | wx      |     500 |           6 |
+-----------+---------+---------+-------------+
6 rows in set (0.00 sec)

# 按照balance字段排序,first_value()选出排第一的余额
mysql> select name,channel,balance,first_value(balance) over(order by balance) as first1 from account_channel;
+-----------+---------+---------+--------+
| name      | channel | balance | first1 |
+-----------+---------+---------+--------+
| zhuge     | wx      |     100 |    100 |
| lilei     | alipay  |     100 |    100 |
| zhuge     | alipay  |     200 |    100 |
| lilei     | wx      |     200 |    100 |
| zhuge     | yinhang |     300 |    100 |
| hanmeimei | wx      |     500 |    100 |
+-----------+---------+---------+--------+
6 rows in set (0.01 sec)

11、默认字符集由latin1变为utf8mb4

MySQL 5.7:默认字符集为latin1,utf8指向的是utf8mb3

MySQL 8.0:默认字符集为utf8mb4,utf8默认指向的也是utf8mb4

12、MyISAM系统表全部换成InnoDB表

MySQL 8.0:系统表和数据字典表全部改为InnoDB存储引擎

13、元数据存储变动

MySQL 8.0:删除之前版本的元数据文件,例如表结构.frm等文件,全部集中放入mysql.ibd文件里。如图所示,test库文件夹里已经没有了frm文件
在这里插入图片描述
在这里插入图片描述

14、自增变量持久化

MySQL 5.7:在MySQL重启后,会重置AUTO_INCREMENT=max(primary key)+1,在某些业务场景下会报主键冲突的错误或其它难以发现的问题

MySQL 8.0:对AUTO_INCREMENT值进行持久化,MySQL重启后,该值将不会改变

# ====MySQL 5.7演示====
mysql> create table t(id int auto_increment primary key,c1 varchar(20));
Query OK, 0 rows affected (0.03 sec)

mysql> insert into t(c1) values('zhuge1'),('zhuge2'),('zhuge3');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
|  3 | zhuge3 |
+----+--------+
3 rows in set (0.00 sec)

mysql> delete from t where id = 3;
Query OK, 1 row affected (0.01 sec)

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
+----+--------+
2 rows in set (0.00 sec)

mysql> exit;
Bye

# 如果不重启Mysql服务,插入一条数据它的主键Id就是4

# 但是重启MySQL服务,并重新连接MySQL。它会重置自增ID,从3开始
mysql> insert into t(c1) values('zhuge4');
Query OK, 1 row affected (0.01 sec)

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
|  3 | zhuge4 |
+----+--------+
3 rows in set (0.00 sec)
# ====MySQL 8.0演示====
mysql> create table t(id int auto_increment primary key,c1 varchar(20));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t(c1) values('zhuge1'),('zhuge2'),('zhuge3');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
|  3 | zhuge3 |
+----+--------+
3 rows in set (0.00 sec)

mysql> delete from t where id = 3;
Query OK, 1 row affected (0.01 sec)

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
+----+--------+
2 rows in set (0.00 sec)

mysql> exit;
Bye
[root@localhost ~]# service mysqld restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL... SUCCESS! 

# 重新连接MySQL
mysql> insert into t(c1) values('zhuge4');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;  --生成的id为4,不是3
+----+--------+
| id | c1     |
+----+--------+
|  1 | zhuge1 |
|  2 | zhuge2 |
|  4 | zhuge4 |
+----+--------+
3 rows in set (0.00 sec)

mysql> update t set id = 5 where c1 = 'zhuge1';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  2 | zhuge2 |
|  4 | zhuge4 |
|  5 | zhuge1 |
+----+--------+
3 rows in set (0.00 sec)

mysql> insert into t(c1) values('zhuge5');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+----+--------+
| id | c1     |
+----+--------+
|  2 | zhuge2 |
|  4 | zhuge4 |
|  5 | zhuge1 |
|  6 | zhuge5 |
+----+--------+
4 rows in set (0.00 sec)

15、DDL原子化

InnoDB表的DDL支持事务完整性,要么成功要么回滚。

MySQL 8.0 开始支持原子 DDL 操作,其中与表相关的原子 DDL 只支持 InnoDB 存储引擎。一个原子 DDL 操作内容包括:更新数据字典,存储引擎层的操作,在 binlog 中记录 DDL 操作。支持与表相关的 DDL:数据库、表空间、表、索引的 CREATE、ALTER、DROP 以及 TRUNCATE TABLE。支持的其它 DDL :存储程序、触发器、视图、UDF 的 CREATE、DROP 以及ALTER 语句。支持账户管理相关的 DDL:用户和角色的 CREATE、ALTER、DROP 以及适用的 RENAME等等。

# MySQL 5.7
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| account        |
| actor          |
| employee       |
| film           |
| film_actor     |
| leaf_id        |
| t1             |
| test_innodb    |
| test_myisam    |
| test_order_id  |
+----------------+
10 rows in set (0.01 sec)

mysql> drop table t1,t2;  //删除表报错不会回滚,t1表会被删除
ERROR 1051 (42S02): Unknown table 'test.t2'
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| account        |
| actor          |
| employee       |
| film           |
| film_actor     |
| leaf_id        |
| test_innodb    |
| test_myisam    |
| test_order_id  |
+----------------+
9 rows in set (0.00 sec)
# MySQL 8.0  
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| account        |
| actor          |
| employee       |
| film           |
| film_actor     |
| leaf_id        |
| t1             |
| test_innodb    |
| test_myisam    |
| test_order_id  |
+----------------+
10 rows in set (0.00 sec)

mysql> drop table t1,t2;  //删除表报错会回滚,t1表依然还在
ERROR 1051 (42S02): Unknown table 'test.t2'
mysql> show tables;  
+----------------+
| Tables_in_test |
+----------------+
| account        |
| actor          |
| employee       |
| film           |
| film_actor     |
| leaf_id        |
| t1             |
| test_innodb    |
| test_myisam    |
| test_order_id  |
+----------------+
10 rows in set (0.00 sec)

16、参数修改持久化

MySQL 5.7:set global 设置的变量参数在mysql重启后会失效
MySQL 8.0:支持在线修改全局参数并持久化,通过加上PERSIST关键字,可以将修改的参数持久化到新的配置文件(mysqld-auto.cnf)中。重启MySQL时,会从该配置文件获取到最新的配置参数

mysql> set persist innodb_lock_wait_timeout=25;
系统会在数据目录下生成一个包含json格式的mysqld-auto.cnf 的文件,格式化后如下所示,当my.cnf 和mysqld-auto.cnf 同时存在时,后者具有更高优先级。
{
    "Version": 1,
    "mysql_server": {
        "innodb_lock_wait_timeout": {
            "Value": "25",
            "Metadata": {
                "Timestamp": 1675290252103863,
                "User": "root",
                "Host": "localhost"
            }
        }
    }
}```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1633220.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytest教程-34-钩子函数-pytest_configure

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest_addoption钩子函数的使用方法,本小节我们讲解一下pytest_configure钩子函数的使用方法。 pytest_configure(config) 是一个 pytest 钩子函数,它在 pytest 配置完…

资产管理软件价格 一套固定资产管理系统多少钱

固定资产管理系统作为一款帮助工厂、事业单位、政府机关等企业管理资产设备的管理工具,其实,一直在向企业提供着各种相关的服务,对于才接触固定资产管理系统的朋友们来说,首先想要了解的这个付费工具的收费问题,那这个…

关于谷歌浏览器对于https的证书不通过校验的无法跳转的问题

谷歌浏览器对于https的证书问题会出现如下提示: 解决方法: 直接在页面输入 thisisunsafe 就能跳转了.

精彩回顾|从 AI 到银幕:顶尖对话揭秘 AI 如何塑造影视新格局

4月17日,由万合天宜、三次元影业、NOVATECH、微软中国极客天团、微软 Reactor 共同推出的「从 AI 到银幕」顶尖对话在上海微软紫竹园区举办。中国内地著名导演、编剧、监制黄建新,微软(中国)有限公司首席技术官韦青,与…

孕线反转形态,Anzo Capital10年交易经验一眼看穿

很多投资者都知道Inside-bar孕线是一种很好的反转信号,但是不了解Inside-bar孕线如何一眼发现孕线反转形态,今天Anzo Capital昂首资本平台上的10年交易者进行免费分享,希望各位投资者能够一眼看穿孕线反转形态: 首先各位投资者发散一下思维&…

美国站群服务器上常见的操作系统选择指南

美国站群服务器上常见的操作系统选择指南 美国站群服务器的选择操作系统对于服务器的性能和功能至关重要。本文将为您介绍在美国站群服务器上常见的操作系统选择指南,以帮助您做出明智的决策。 在选择美国站群服务器时,选择合适的操作系统是至关重要的…

Qt QLineEdit详解

1.简介 QLineEdit是一个单行文本编辑器。 行编辑允许用户使用一组有用的编辑功能输入和编辑单行纯文本,包括撤消和重做、剪切和粘贴以及拖放。 通过更改行编辑的echoMode,它也可以用作“只写”字段,用于密码等输入。 文本的长度可以限制为ma…

【每日刷题】Day28

【每日刷题】Day28 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 ​ 1. 121. 买卖股票的最佳时机 - 力扣(LeetCode) 2. 205. 同构字符串 - 力扣…

充电桩---ISO15118协议详细介绍

一、ISO15118介绍 1、发展背景 标准于 2010 年由国际标准化组织(ISO)和国际电工委员会(IEC)通过,电动汽车和充电站之间的通信,改善了不同品牌、型号和充电类型(交流或直流)之间的互…

React配置@别名路径配置

1. 背景知识 路径解析配置(webpack),把 / 解析为 src/路径联想配置(VsCode),VsCode 在输入 / 时,自动联想出来对应的 src/下的子级目录 2. 路径解析配置 配置步骤: 安装craco npm …

K8s: Prometheus 服务结构以及基础抓取数据服务部署

Prometheus 发布应用之后,就有持续运维的事情,就是平台监控Prometheus 是一个云原生的日志监控平台,是一个实时标准的一个技术它是著名的 cncf 里的一个重要的开源项目 上面整个图片是在云原生应用及K8s应用架构下的一个日志监控的一个标准的…

用数据说话,还你一个SSD和HDD的真相

【全球存储观察 | 热点关注】在全球数据存储领域,NAND盖楼大赛从来就没有消停过,为什么? 纵观全球NAND主流供应商,三星电子、铠侠、美光科技、SK海力士等,基于自己在闪存技术积累与创新,纷纷热…

nginx--安装

yum安装 官方包链接:nginx: Linux packages 官方yum源链接:nginx: Linux packages 配置yum源 [rootlocalhost ~]# yum install -y nginx [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gp…

【论文阅读】ELAN-Efficient Long-Range Attention Network for Image Super-resolution

ELAN-Efficient Long-Range Attention Network for Image Super-resolution 论文地址简介1 引言2相关工作2.1 基于 CNN 的 SR 方法2.2 基于 Transformer 的 SR 方法 3 方法论3.1 ELAN 的整体流程3.2 Efficient Long-range Attention Block (ELAB) 4实验4.1实验设置4.2 与轻量级…

从注册到订阅,Midjourney使用指南,你想知道的都有

Midjourney简介 Midjourney官网:https://www.midjourney.com/home 是一个独立的研究实验室,专注于探索新的思维方式和扩展人类的想象力。它由一个小型的自筹资金团队组成,该团队专注于设计、人类基础设施和人工智能。Midjourney拥有11名全职…

ipad的文件如何传到手机里 iPad较大文件怎么发送出去 iMazing下载教程

在现代生活中,随着移动设备的普及和多样化,我们经常需要在不同设备之间传输文件,以便在工作、学习或娱乐中更加便捷地使用这些文件。iPad和iPhone是用户广泛使用的设备,我们时常使用它们来存储和访问大量的个人数据。但有时&#…

安装 AngularJS

安装 AngularJS 文章目录 安装 AngularJS1. 使用在线 cdn2. 使用依赖管理工具 npm 1. 使用在线 cdn <!-- 1. 引入在线地址 --> <script src"http://code.angularjs.org/1.2.25/angular.min.js"></script><!-- 2. 下载到本地&#xff0c;引入文…

Apache Seata基于改良版雪花算法的分布式UUID生成器分析2

title: 关于新版雪花算法的答疑 author: selfishlover keywords: [Seata, snowflake, UUID, page split] date: 2021/06/21 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 关于新版雪花算法的答疑 在上一篇关于新版雪花算法的解析中…

Django框架视图基础

本节主要介绍Django框架视图的基础知识。Django视图层是负责处理请求的核心&#xff0c;是开发Web应用的重要组成部分。Django视图层代码可以放在应用目录下的任何位置&#xff0c;通常写在类似views.py这样的文件中。 在Django框架视图层的概念体系中&#xff0c;视图函数简称…

探索项目管理系统:解析五大功能,洞悉项目成功的关键

项目管理新手往往喜欢埋头苦干&#xff0c;殊不知优秀的项目经理已经熟练运用项目管理系统&#xff0c;让项目规划条理清晰。项目管理系统具备的功能&#xff0c;好用的项目管理系统都有这5大功能。分别是项目WBS分解、项目图表和报表、工时管理、团队协作、任务流程自动化。 一…