Mysql 5.7新特性: JSON字段、虚拟列、视图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 5.7新特性: JSON字段、虚拟列、视图相关的知识,希望对你有一定的参考价值。

参考技术A

alter table ba_bgt_info add v_is_auto varchar(300) generated always AS(manage_categories->"$.isAuto")

mysql 5.7中,支持两种Generated Column,即Virtual Generated Column和Stored Generated Column,前者只将Generated Column保存在数据字典中(表的元数据),并不会将这一列数据持久化到磁盘上;后者会将Generated Column持久化到磁盘上,而不是每次读取的时候计算所得。很明显,后者存放了可以通过已有数据计算而得的数据,需要更多的磁盘空间,与Virtual Column相比并没有优势,因此,MySQL 5.7中,不指定Generated Column的类型,默认是Virtual Column。
如果需要Stored Generated Golumn的话,可以在Virtual Generated Column上建立索引更加合适
综上,一般情况下,都使用Virtual Generated Column,这也是MySQL默认的方式
能正常加索引、特殊用途冗余列、列长度还是和定义类型一样、查询效率上,物理>STORED>VIRTUAL

虚拟列: 一个或多个字段的数据函数处理后的结果集映射成的字段
视图: 一个或多个表依照某个条件组合而成的结果集(相当于一个查询sql语句的结果集映射成的虚拟表)
其本质其实都是以空间换时间

什么是视图?视图是干什么用的?
视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。
通过视图,可以展现基表的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。
基表: 用来创建视图的表叫做基表base table

因为视图的诸多优点,如下

总而言之,使用视图的大部分情况是为了保障数据安全性,提高查询效率。

如何创建一个虚拟列来索引 MySQL 中的 JSON 列?

【中文标题】如何创建一个虚拟列来索引 MySQL 中的 JSON 列?【英文标题】:How to create a virtual column to index JSON column in MySQL? 【发布时间】:2021-09-08 02:05:54 【问题描述】:

我正在使用MySql 8.0 verion,我的表格如下所示:

CREATE TABLE `table1` (
  `id` int(11) NOT NULL,
  `tableType` varchar(45) DEFAULT NULL,
  `jkey` varchar(45) DEFAULT NULL,
  `jval` json DEFAULT NULL,
  PRIMARY KEY (`id`)
) 

这里jval总是有2个字段如下:

"group": "group1@abc.com", "user": "user1"

"group": "group2@abc.com", "user": "user2"

我正在尝试将索引添加到 JSON column jval 但出现以下错误:

Operation failed: There was an error while applying the SQL script to the database.
ERROR 3152: JSON column 'jval' supports indexing only via generated columns on a specified JSON path.
SQL Statement:
ALTER TABLE `db1`.`table1` 
ADD INDEX `jval` (`value` ASC) VISIBLE

如何在 MySQL 中创建一个 virtual column 来索引 jval

【问题讨论】:

能分享一下你的mysql版本吗?玛丽亚? MySql 8.0 版本 MySQL 没有直接索引 JSON 文档的方法,但它为我们提供了另一种选择:生成列。我们可以索引一个 JSON 字段。可以分享一下示例json和要索引的字段吗 这里 jval 将有 2 个值,如下所示:group1@abc.com, sme1 group2@abc.com, sme2 它不是一个有效的 json。只需共享一个正确的 json 和要编入索引的 field 【参考方案1】:

MySQL 无法直接索引 JSON 文档,但它为我们提供了另一种选择:生成列。 通过从 JSON 文档中的值生成列,然后为该列建立索引,我们实际上可以为 JSON 字段建立索引。

Generated Columns 的语法是

column_name 数据类型始终作为(表达式)生成

你的查询会变成这样

CREATE TABLE `table1` (
  `id` int(11) NOT NULL,
  `tableType` varchar(45) DEFAULT NULL,
  `jkey` varchar(45) DEFAULT NULL,
  `jval` json NOT NULL,

  `group_virtual` VARCHAR(250) GENERATED ALWAYS AS (`jval` ->> '$.group') NOT NULL, 
  `user_virtual` VARCHAR(250) GENERATED ALWAYS AS (`jval` ->> '$.user') NOT NULL,   
  
  PRIMARY KEY (`id`)
);

您可以检查虚拟列

SHOW COLUMNS FROM `table1`;
Field Type Null Key Default Extra
id 696e74 NO PRI
tableType 7661726368617228343529 YES
jkey 7661726368617228343529 YES
jval 6a736f6e NO
group_virtual 766172636861722832353029 NO VIRTUAL GENERATED
user_virtual 766172636861722832353029 NO VIRTUAL GENERATED

如果表已经创建并且您想要创建生成的列,则使用以下语法

ALTER TABLE
    `table1` ADD COLUMN `user_virtual` VARCHAR(250) 
     GENERATED ALWAYS AS(`jval` - >> '$.user') NOT NULL 
AFTER `jval`;

不要忘记为生成的列建立索引

CREATE INDEX `users_idx` ON `table1`(`user_virtual`); 

那就试试

SHOW INDEX FROM table1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Visible Expression
table1 0 PRIMARY 1 id A 0 null null BTREE YES
table1 1 users_idx 1 user_virtual A 0 null null BTREE YES

db小提琴here

【讨论】:

感谢因陀罗的回答。我已经创建了表格。那么,您能否建议在这种情况下Alter statement 是什么? 其实,CreateAlter 两个语句都有利于以后参考。 @meallhour 请检查更新后的答案。你需要做 2 件事 1) 生成一个虚拟列 2) 并索引生成的列

以上是关于Mysql 5.7新特性: JSON字段、虚拟列、视图的主要内容,如果未能解决你的问题,请参考以下文章

使用mysql innodb 使用5.7的json类型遇到的坑和解决办法

MySQL——MySQL 5.7新特性

MySQL 5.7新特性之Generated Column(函数索引)

Mysql 5.7 JSON 与 物联网设备上数完美结合

Mysql 5.7 JSON 与 物联网设备上数完美结合

第十三期分享:MYSQL8.0新特性