微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 MySQL 8 在 JSON 数组上创建索引

如何解决如何使用 MySQL 8 在 JSON 数组上创建索引

我在 MysqL 8 中有一个 JSON 字段,如下所示:

[{"key": "apples","string_values": ["red"]},{"key": "oranges","string_values": ["orange"]}]

有没有办法在字符串值上创建索引?我希望我能做这样的事情:

ALTER TABLE mytable ADD INDEX myindex( 
    (CAST(Metadata->'$[*].string_values' AS UNSIGNED ARRAY)) 
);

但是返回以下错误:无法在索引的标量键部分中存储数组或对象

小提琴例如:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ae36a5169094ae67a290febf09f49f0c

编辑:

我开始认为我能做到这一点的唯一方法是使用生成的列:

以下选择现在将命中索引。

ALTER TABLE mytable ADD string_values JSON AS (JSON_EXTRACT(Metadata,'$[*].string_values[0]'));

ALTER TABLE mytable ADD INDEX idx_string_values( 
    (CAST(string_values->'$' AS CHAR(100) ARRAY))
);

SELECT * FROM mytable WHERE 'red' MEMBER OF(string_values->'$');

解决方法

有 2 个不同的问题。


首先是可以解决的。下一个小提琴描述它:

CREATE TABLE mytable (metadata JSON);
INSERT INTO mytable VALUES ('[{"key": "apples","string_values": ["red"]},{"key": "oranges","string_values": ["orange"]}]');
-- you try to index arrays
SELECT metadata->'$[*].string_values' FROM mytable;
-- but you need in scalar values
SELECT metadata->'$[*].string_values[0]' FROM mytable;
| metadata->'$[*].string_values' |
| :----------------------------- |
| [["red"],["orange"]]          |

| metadata->'$[*].string_values[0]' |
| :-------------------------------- |
| ["red","orange"]                 |

dbfiddle here


第二个问题无法解决。

仔细查看您尝试创建索引时使用的语句:

ALTER TABLE mytable ADD INDEX myindex((CAST(metadata->'$[*].string_values' AS UNSIGNED ARRAY)));

数组 ["red","orange"] 中的值不是数字。

,

在回答之前,我应该做一个简短的免责声明。在 SQL 数据库中存储 JSON 数据实际上违背了基本的 SQL 设计理念。 SQL,顾名思义,用于结构化,即强类型数据。如果您将数据作为 JSON 传递到 SQL 数据库,您实际上是在丢弃其结构并将其视为字符串。

因此,在这种情况下,我会首先考虑以下两种选择:

(A) 我可以将这些数据视为结构化数据吗?在这种情况下,我将创建一个表,其中的列对应于 JSON 字段,然后像为任何其他列一样创建索引。

(B) 我的数据基本上是非结构化的吗?在这种情况下,我会尝试将其建模为 SQL 中的键值对,或者使用非 SQL 数据库,例如 CouchDB 或 Elasticsearch。

使用基于键值的方法,您可以将有问题的属性分离到一个单独的表中(对于将是键/索引/值的数组),然后您可以将其用于索引。这当然会增加一些开销,这取决于具体情况,在您的情况下可能会或可能不会被接受。

但是,仍然有很多合理的理由为什么某些东西可能不被归类为 A 或 B。如果您已经考虑并尝试了这两种方法,并且您可以清楚地证明为什么您的情况是例外的:

(C) 读取 the MySQL documentation about indexing generated columns

即便如此,您可能仍需要重构您的 JSON 数据,例如将数组转换为单个条目(id/index/value)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。