【问题标题】:How to INDEX JSON ARRAY stored in own column如何索引 JSON ARRAY 存储在自己的列中
【发布时间】:2020-11-01 01:08:56
【问题描述】:

我有这张桌子:

CREATE TABLE `datacollector` (
  `id` binary(16) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `processed` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'N',
  `processed_at` timestamp NULL DEFAULT NULL,
  `request` json NOT NULL,
  `response` json NOT NULL,
  `response_date` timestamp GENERATED ALWAYS AS (from_unixtime(json_unquote(json_extract(`response`,_utf8mb4'$.date')))) VIRTUAL NULL,
  `sha224` varchar(80) COLLATE utf8mb4_unicode_ci NOT NULL,
  `available_for` json NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_sha224` (`sha224`),
  KEY `created_at` (`created_at`) /*!80000 INVISIBLE */,
  KEY `cmoa` (`created_at`,`processed`) /*!80000 INVISIBLE */,
  KEY `response_date` (`response_date`) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

我使用在available_for 中创建字符串数组的触发器。现在我想为available_for 创建一个索引。

我已经试过了

ALTER TABLE `hwtools`.`datacollector` 
ADD INDEX `available_for_idx` ((CAST(json_unquote(available_for) AS UNSIGNED ARRAY)));

或

ALTER TABLE `hwtools`.`datacollector` 
ADD INDEX `available_for_idx` ((CAST(available_for AS UNSIGNED ARRAY)));

这总是给我一个错误。

存储在 available_for 中的 JSON 看起来像 '["getUserInfo", "stashClient"]'。

我现在如何使用最后一个 MySQL 8 创建正确的索引?

感谢您对我的问题的意见。

【问题讨论】:

  • 确切的错误信息是什么? json 值似乎是字符串,而不是无符号整数。为什么使用 unsigned 作为数组类型?
  • 因为无法使用 Varchar...13:21:41 ALTER TABLE hwtools.datacollector ADD INDEX available_for_idx ((CAST(available_for AS VARCHAR(32) ARRAY))) VISIBLE Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARCHAR(32) ARRAY))) VISIBLE' at line 2 0.031 sec
  • 还有14:39:00 ALTER TABLE hwtools.datacollector ADD INDEX available_for_idx ((CAST(available_for AS CHAR ARRAY))) VISIBLE Error Code: 1235. This version of MySQL doesn't yet support 'CAST-ing data to array of char/binary BLOBs' 0.031 sec
  • 你应该使用char,而不是varchar,但是第二个错误表明你的版本可能还不支持这个功能。
  • 您希望在 JSON 列上建立什么索引?索引键是有意义的,但索引文档没有。请包含您要优化的查询。

标签: mysql arrays json


【解决方案1】:

Multi-Valued Indexes 仅在使用 InnoDB 引擎的 MySQL 8.0.17 之后才受支持。

您还需要注意您投射数组的什么类型。 unsigned array 是一个无符号整数数组。对于字符串数组,请使用 char(255) array 或类似名称。

这个 DDL 应该可以正常工作:

CREATE TABLE `datacollector` (
  `id` binary(16) NOT NULL,
  `available_for` json NOT NULL,
  PRIMARY KEY (`id`),
  KEY available_for_idx ((CAST(available_for AS char(255) ARRAY)))
) ENGINE=InnoDB;

编辑:我想补充说明。与每个表行只有一个索引节点的传统索引不同,手册解释说:

多值索引对于一个[/every]单个数据记录(N:1)可以有多个索引记录。

这对我来说是个新闻。你每天都会学到新东西。

【讨论】:

  • 谢谢,我错过了char(255),这就是它不起作用的原因。
  • 您希望该索引适合什么样的搜索?除了严格/身份平等之外,我认为它没有多大用处。
  • @TheImpaler,我认为它甚至可以优化对行索引数组的单个成员的搜索。见dev.mysql.com/doc/refman/8.0/en/…
  • 有趣。 . .
  • @TheImpaler 原因是 MySQL 不直接支持数组存储和索引。因此,存储数组的一种策略是将它们存储为 JSON 数组(文档),并为该列添加 MVI。
猜你喜欢
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 2013-03-08
相关资源
最近更新 更多