网易迁移方案设计 DDB 迁移到 TiDB
579
2023-05-24
MySQL 8.0.23新特性 - 不可见列
在新的MySQL 8.0.23中,引入了新的有趣功能:不可见列。
这是第一篇关于这个新功能的文章,我希望写一个3篇的系列。这是前言。
在MySQL 8.0.23之前,表中所有的列都是可见的(如果您有权限的话)。现在可以指定一个不可见的列,它将对查询隐藏。如果显式引用,它可以被查到。
让我们看看它是怎样的:
create table table1 ( id int auto_increment primary key, name varchar(20), age int invisible);
在表结构中我们在Extra列可以看到INVISIBLE 关键字:
desc table1; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | age | int | YES | | NULL | INVISIBLE | +-------+-------------+------+-----+---------+----------------+
查看show create table语句,注意到有一个不同,当我创建表时,我希望看到INVISIBLE 关键字,但事实并非如此:
show create table table1\\G ************************* 1. row ************************* Table: table1 Create Table: CREATE TABLE `table1` ( id int NOT NULL AUTO_INCREMENT, name varchar(20) DEFAULT NULL, age int DEFAULT NULL /*!80023 INVISIBLE */, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
但是我确认这个语句在创建表时会将age 列设置为不可见。所以我们有2个不同的语法来创建不可见列。
INFORMATION_SCHEMA 中也可以看到相关信息:
SELECT TABLE_NAME, COLUMN_NAME, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'table1'; +------------+-------------+----------------+ | TABLE_NAME | COLUMN_NAME | EXTRA | +------------+-------------+----------------+ | table1 | id | auto_increment | | table1 | name | | | table1 | age | INVISIBLE | +------------+-------------+----------------+
插入一些数据,继续观察:
insert into table1 values (0,'mysql', 25), (0,'kenny', 35), (0, 'lefred','44'); ERROR: 1136: Column count doesn't match value count at row 1
如预期,插入语句中如果我们不引用它,会报错。引用这些列:
insert into table1 (id, name, age) values (0,'mysql', 25), (0,'kenny', 35), (0, 'lefred','44'); Query OK, 3 rows affected (0.1573 sec
查询表中数据:
select * from table1; +----+--------+ | id | name | +----+--------+ | 1 | mysql | | 2 | kenny | | 3 | lefred | +----+--------+
再一次,如预期,我们看到不可见列没有显示。
如果我们指定它:
select name, age from table1; +--------+-----+ | name | age | +--------+-----+ | mysql | 25 | | kenny | 35 | | lefred | 44 | +--------+-----+
当然我们可以将列从可见转为不可见或者将不可见转为可见:
alter table table1 modify name varchar(20) invisible, modify age integer visible; Query OK, 0 rows affected (0.1934 sec) select * from table1; +----+-----+ | id | age | +----+-----+ | 1 | 25 | | 2 | 35 | | 3 | 44 | +----+-----+
我对这个新功能感到非常高兴,在下一篇文章中我们将会看到为什么这对InnoDB来说是一个重要的功能。
本文是与MySQL不可见列相关的系列文章的第二部分。
这篇文章介绍了为什么不可见列对InnoDB存储引擎很重要。
首先,让我简单解释一下InnoDB是如何处理主键的,以及为什么一个好的主键很重要。最后,为什么主键也很重要。
InnoDB如何存储数据?
InnoDB在表空间存储数据。这些记录存储并用聚簇索引排序(主键):它们被称为索引组织表。
所有的二级索引也将主键作为索引中的最右边的列(即使没有公开)。这意味着当使用二级索引检索一条记录时,将使用两个索引:二级索引指向用于最终检索该记录的主键。
主键会影响随机I/O和顺序I/O之间的比率以及二级索引的大小。
随机主键还是顺序主键?
如上所述,数据存储在聚簇索引中的表空间中。这意味着如果您不使用顺序索引,当执行插入时,InnoDB不得不重平衡表空间的所有页。
如果我们用InnoDB Ruby来说明这个过程,下面的图片显示了当使用随机字符串作为主键插入记录时表空间是如何更新的:
每次有一个插入,几乎所有的页都会被触及。
当使用自增整型作为主键时,同样的插入:
自增主键的情况下,只有第一个页和最后一个页才会被触及。
让我们用一个高层次的例子来解释这一点:
插入新记录,主键为AA!
修改所有页以"重新平衡"聚簇索引,在连续主键的情况下,只有最后一个页面会被修改。想象一下成千上万的插入发生时所要做的额外工作。
这意味着选择好的主键是重要的。需要注意两点:
主键必须连续。 主键必须短。
UUID怎么样?
我通常建议使用自增整型(或bigint)作为主键,但是不要忘记监控它们!
但我也明白越来越多的开发人员喜欢使用uuid。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。