如何在 MySQL 中创建虚拟列来索引 JSON 列?

mea*_*our 1 mysql indexing json join mysql-workbench

我正在使用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`)
) 
Run Code Online (Sandbox Code Playgroud)

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

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

{"group": "group2@abc.com", "user": "user2"}
Run Code Online (Sandbox Code Playgroud)

我正在尝试将索引添加到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
Run Code Online (Sandbox Code Playgroud)

如何在 MySQL 中创建virtual columnto 索引jval

Ind*_*r S 13

MySQL 没有直接索引 JSON 文档的方法,但它为我们提供了一种替代方案:生成列。通过根据 JSON 文档中的值生成列,然后对该列建立索引,我们实际上可以对 JSON 字段建立索引。

语法Generated Columns

column_name数据类型 GENERATED ALWAYS AS(表达式)

你的查询会变成这样

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`)
);
Run Code Online (Sandbox Code Playgroud)

您可以检查虚拟列

SHOW COLUMNS FROM `table1`;
Run Code Online (Sandbox Code Playgroud)
场地 类型 无效的 钥匙 默认 额外的
ID 696e74 优先原则
表类型 7661726368617228343529 是的
杰基 7661726368617228343529 是的
杰瓦尔 6a736f6e
虚拟组 766172636861722832353029 虚拟生成
用户虚拟 766172636861722832353029 虚拟生成

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

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

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

CREATE INDEX `users_idx` ON `table1`(`user_virtual`); 
Run Code Online (Sandbox Code Playgroud)

然后尝试

SHOW INDEX FROM table1;
Run Code Online (Sandbox Code Playgroud)
桌子 非唯一 键名 索引中的序列 列名 整理 基数 子部分 包装好的 无效的 索引类型 评论 索引_评论 可见的 表达
表格1 0 基本的 1 ID A 0 无效的 无效的 BT树 是的
表格1 1 用户idx 1 用户虚拟 A 0 无效的 无效的 BT树 是的

db<>在这里摆弄