如何创建一个虚拟列来索引 MySQL 中的 JSON 列?
How to create a virtual column to index JSON column in MySQL?
我正在使用 MySql 8.0 verion
,我的 table 如下所示:
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
如何创建 virtual column
以在 MySQL 中索引 jval
?
MySQL 没有办法直接索引 JSON 文档,但它给了我们一个替代方案:生成列。 通过从 JSON 文档中的值生成列然后索引该列,我们实际上可以索引一个 JSON 字段。
Generated Columns
的语法是
column_name
datatype GENERATED ALWAYS AS (expression)
你的查询会变成这样
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
如果 table 已经创建并且您想创建生成的列,则使用以下语法
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<>fiddle here
我正在使用 MySql 8.0 verion
,我的 table 如下所示:
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
如何创建 virtual column
以在 MySQL 中索引 jval
?
MySQL 没有办法直接索引 JSON 文档,但它给了我们一个替代方案:生成列。 通过从 JSON 文档中的值生成列然后索引该列,我们实际上可以索引一个 JSON 字段。
Generated Columns
的语法是
column_name
datatype GENERATED ALWAYS AS (expression)
你的查询会变成这样
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 |
如果 table 已经创建并且您想创建生成的列,则使用以下语法
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<>fiddle here