在这篇文章中,我想讨论一些漂亮的新特性在MySQL 8.0 -和一个年长的一个。也许你没有意识到这些都是次要的功能,也许不太相关,说实话。但值得提供一个快速概述,展示它们是如何工作的,以及他们如何在某些情况下可能是有用的。
指的是隐形的东西:
- 看不见的列
- 看不见的主键生成
- 看不见的索引
让我们看一看。
看不见的列
看不见的列功能8.0.23以来部署版本。一个看不见的列是什么?它基本上是一个常规表的列的名称和数据类型。治疗和定期更新和其他列,唯一不同的是,它是无形的给应用程序。换句话说,它可以访问只有在明确解决在你的选择;否则,它就像一个不存在的列。
定义看起来奇怪,但一切都应该更清楚,该特性提供一个真正的用例。
假设你有SELECT *查询在您的应用程序代码。作为一个经验丰富的数据库开发人员,你应该知道这些类型的查询不应该存在于任何生产代码。典型的问题是当你需要改变表的模式,添加或删除列,或者更糟的是,添加一个新列中。字段获取到您的应用程序中变量的位置完全打破应用程序或可能引发意想不到的不当行为。这就是为什么你需要避免在应用程序中使用SELECT *像躲避瘟疫一样。
来了看不见的列。在这种情况下,如果你需要避免改变应用程序代码与新表模式,您可以添加新列一个看不见的,它不会返回给客户端,因为它没有显式地处理你的查询。所以,不为您的应用程序失败或奇怪的行为。
你需要使用看不见的列定义的关键字。当你需要把一个列可见,您需要使用可见关键字来代替。让我们看看一个例子。
创建一个表为我们的文章和插入几行:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
mysql
&
gt
;
创建
表
文章
(
id
INT
无符号
AUTO_INCREMENT
,
ts
时间戳
默认的
CURRENT_TIMESTAMP
,
文章
文本
,
主
关键
(
id
)
)
;
查询
好吧
,
0
行
影响
(
0.03
证券交易委员会
)
mysql
&
gt
;
插入
成
文章
(
文章
)
值
(
“这是第一篇文章”
)
,
(
“这是第二篇文章”
)
,
(
“这是第三篇文章”
)
;
查询
好吧
,
3
行
影响
(
0.01
证券交易委员会
)
记录
:
3
重复的
:
0
警告
:
0
mysql
&
gt
;
SELECT *
从
文章
;
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
id
|
ts
|
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
1
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第一个
文章
|
|
2
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第二个
文章
|
|
3
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第三
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
在某种程度上,我们决定新领域标题必须添加到表后ts列。为了避免我们的应用程序由于SELECT *的失效和新添加的列在中间,我们必须创建标题列是无形的。
|
1
2
3
|
mysql
&
gt
;
改变
表
文章
添加
列
标题
VARCHAR
(
200年
)
看不见的
后
ts
;
查询
好吧
,
0
行
影响
(
0.06
证券交易委员会
)
记录
:
0
重复的
:
0
警告
:
0
|
让我们提供一些新列值:
|
1
|
mysql
&
gt
;
更新
文章
集
标题
=
“标题1”
在哪里
id
=
1
;
更新
文章
集
标题
=
“标题2”
在哪里
id
=
2
;
更新
文章
集
标题
=
“标题3”
在哪里
id
=
3
;
|
看到现在的表模式:
|
1
2
3
4
5
6
7
|
创建
表
”
文章
”
(
”
id
”
int
无符号
不
零
AUTO_INCREMENT
,
”
ts
”
时间戳
零
默认的
CURRENT_TIMESTAMP
,
”
标题
”
varchar
(
200年
)
默认的
零
/ * !80023看不见的*/
,
”
文章
”
文本
,
主
关键
(
”
id
”
)
)
引擎
=
InnoDB
AUTO_INCREMENT
=
4
默认的
字符集
=
utf8mb4
核对
=
utf8mb4_0900_ai_ci
|
你看,列与无形的关键字正确的标记。
,现在又SELECT *:
|
1
2
3
4
5
6
7
8
|
mysql
&
gt
;
SELECT *
从
文章
;
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
id
|
ts
|
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
1
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第一个
文章
|
|
2
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第二个
文章
|
|
3
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
这
是
第三
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
你看,列不回来了。这允许查询没有失败后的模式改变了。
如果你想看到标题,你必须解决领域明确:
|
1
2
3
4
5
6
7
8
|
mysql
&
gt
;
选择
id
,
ts
,
标题
,
文章
从
文章
;
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
id
|
ts
|
标题
|
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
1
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
标题
1
|
这
是
第一个
文章
|
|
2
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
标题
2
|
这
是
第二个
文章
|
|
3
|
2023年
- - - - - -
07年
- - - - - -
28
13
:
15
:
03
|
标题
3
|
这
是
第三
文章
|
+
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
+
|
你可以把以下DDL的列可见:
|
1
|
mysql
&
gt
;
改变
表
文章
修改
列
标题
varchar
(
200年
)
可见
;
|
记住,无形的列被当作其他常规,所以你可以随时读取和更新它们。information_schema可用元数据对隐身,和看不见的/ binlog可见关键词保存,所以所有更改正确复制。
对于进一步的细节,您可以看一下文档:
https://dev.mysql.com/doc/refman/8.0/en/invisible-columns.html
看不见的主键生成
这个功能已经部署在MySQL 8.0.30;这是最近的。生成的无形的主键(GIPK)是一种特殊的无形的列,它只适用于InnoDB表。
你知道你可以创建InnoDB表没有一个明确的主键。这不是一个最佳实践,我们强烈建议您总是在表中创建一个显式的PK。你可能也知道InnoDB创建一个隐藏的如果你不提供一个主键,但GIPK所提供的新特性使主键成为可用的最后可见。隐式创建的隐藏的PK,相反,这是一个长期的特性,可以成为可用的和可见的。
最终的功能是有用的力量没有经验的用户拥有InnoDB表与明确的PK,即使看不见。
让我们看看它是如何工作的。
这个功能在默认情况下是禁用的,所以MySQL将继续表现得像过去。要启用GIPK,你必须设置以下动态系统变量(全球和会话范围):
|
1
|
mysql
&
gt
;
集
(
坚持
]
sql_generate_invisible_primary_key
=
在
;
|
现在让我们创建一个表没有明确的PK:
|
1
2
|
mysql
&
gt
;
创建
表
客户
(
的名字
VARCHAR
(
50
)
)
;
查询
好吧
,
0
行
影响
(
0.03
证券交易委员会
)
|
检查模式:
|
1
2
3
4
5
6
7
8
|
mysql
&
gt
;
显示
创建
表
customerG
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
1。
行*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
表
:
客户
创建
表
:
创建
表
”
客户
”
(
”
my_row_id
”
长整型数字
无符号
不
零
AUTO_INCREMENT
/ * !80023看不见的*/
,
”
的名字
”
varchar
(
50
)
默认的
零
,
主
关键
(
”
my_row_id
”
)
)
引擎
=
InnoDB
默认的
字符集
=
utf8mb4
核对
=
utf8mb4_0900_ai_ci
|
看不见的主键my_row_id被自动创建。
一些笔记:
- 的名字GIPK总是my_row_id。你不能有一个具有相同名称的列在表中
- GIPK数据类型使用AUTO_INCREMENT总是长整型数字符号
有趣的事情是,你可以在查询中使用主键,看看如果明确解决,作为无形的列的描述。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.
21
|
mysql
&
gt
;
插入
成
客户
值
(
“蒂姆。”
)
,
(
“抢劫”
)
,
(
“鲍勃”
)
;
查询
好吧
,
3
行
影响
(
0.00
证券交易委员会
)
记录
:
3
重复的
:
0
警告
:
0
mysql
&
gt
;
选择
my_row_id
,
的名字
从
客户
;
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
|
my_row_id
|
的名字
|
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
|
1
|
蒂姆
|
|
2
|
罗伯
|
|
3
|
鲍勃
|
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
3
行
在
集
(
0.00
证券交易委员会
)
mysql
&
gt
;
选择
my_row_id
,
的名字
从
客户
在哪里
my_row_id
=
2
;
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
|
my_row_id
|
的名字
|
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
|
2
|
罗伯
|
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
+
1
行
在
集
(
0.00
证券交易委员会
)
|
显然,如果你发出SELECT *,主键不是返回:
|
1
2
3
4
5
6
|
mysql
&
gt
;
SELECT *
从
客户
在哪里
my_row_id
=
2
;
+
- - -
- - -
- - -
+
|
的名字
|
+
- - -
- - -
- - -
+
|
罗伯
|
+
- - -
- - -
- - -
+
|
在某种程度上,你可以最终决定让它可见以及更改名称如果你喜欢:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
mysql
&
gt
;
改变
表
客户
修改
”
my_row_id
”
长整型数字
无符号
不
零
auto_increment
可见
;
查询
好吧
,
0
行
影响
(
0.01
证券交易委员会
)
记录
:
0
重复的
:
0
警告
:
0
mysql
&
gt
;
显示
创建
表
customerG
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
1。
行*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
表
:
客户
创建
表
:
创建
表
”
客户
”
(
”
my_row_id
”
长整型数字
无符号
不
零
AUTO_INCREMENT
,
”
的名字
”
varchar
(
50
)
默认的
零
,
主
关键
(
”
my_row_id
”
)
)
引擎
=
InnoDB
AUTO_INCREMENT
=
4
默认的
字符集
=
utf8mb4
核对
=
utf8mb4_0900_ai_ci
|
对于进一步的细节,您可以看一下文档:
https://dev.mysql.com/doc/refman/8.0/en/create-table-gipks.html
看不见的索引
完成的概述无形的东西,让我们讨论无形的索引。这是最古老的隐身特性,介绍了MySQL 8.0的第一个版本。
简单的想法是,你可以使无形的索引来优化器为了测试查询,如果索引的性能并不存在。无论如何,当指数是无形的,它更新当你执行任何DML语句对表(插入、更新、删除、替换)。
您可以使用以下语句设置索引又看不见,可见:
|
1
2
|
改变
表
mytable
改变
指数
my_idx
看不见的
;
改变
表
mytable
改变
指数
my_idx
可见
;
|
一个看不见的指数可以测试一个查询的执行计划不考虑它。大优点是,你不需要该指数下降。记住,该指数下降几乎是瞬时的,但不是重建索引。重建索引可能需要大量的时间和服务器超负荷运行,取决于表的大小。作为一种替代方法,您还可以使用忽略指数()指数暗示,但在这种情况下,您可能会被迫添加索引提示在许多查询在您的应用程序代码。设置索引作为无形的将允许你在很短的时间内开始测试你的查询。你可以退一步,随时可见,而不会丢失任何更新。
注:
- 主键不能被看不见的
- 唯一的索引可以是无形的,但唯一性检查照常执行
- information_schema指数隐形信息是可用的
- 指数隐形正确复制
对于进一步的细节,您可以看一下文档:
https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
结论
从我的角度来看,你不应该使用无形的列,因为作为一个最佳实践,你不应该在任何应用程序部署SELECT *查询。无论如何,在某些紧急情况下,该特性可能是有用的解决问题。然后记住修复你的代码,把无形的列可见。肯定更好。
或多或少,GIPK是一样的。只要你记得提供显式的主键表,你不需要这个功能。不管怎样,它可能是有用的只是为了让一个表没有PK可以创建一个适当的可以使用,成为可见的自在。
看不见的索引呢?这是一个非常简单的功能,但用于运行测试,尤其是当多个索引可以使用,你不确定优化器选择最好的执行计划。
雷竞技下载官网Percona MySQL是最完整,分布稳定、可伸缩的、安全的MySQL开源解决方案,提供企业级的数据库环境最关键业务应用程序…和它的免费使用!





也有能力添加主键复制和复制工作即使源没有主键。
上所述https://dev.mysql.com/doc/refman/8.0/en/create-table-gipks.html
使用
REQUIRE_TABLE_PRIMARY_KEY_CHECK =生成的一部分改变复制源声明。