MySQL 嵌套 JSON 列搜索和提取子 JSON
MySQL nested JSON column search and extract sub JSON
我有一个 MySQL table authors
列 id
、name
和 published_books
。在此,published_books
是 JSON 列。使用示例数据,
id | name | published_books
-----------------------------------------------------------------------
1 | Tina | {
| | "17e9bf8f": {
| | "name": "Book 1",
| | "tags": [
| | "self Help",
| | "Social"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 2",
| | "tags": [
| | "Inspirational"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
2 | John | {
| | "8e8b2470": {
| | "name": "Book 4",
| | "tags": [
| | "Social"
| | ],
| | "language": "Tamil",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
3 | Keith | {
| | "17e9bf8f": {
| | "name": "Book 5",
| | "tags": [
| | "Comedy"
| | ],
| | "language": "French",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 6",
| | "tags": [
| | "Social",
| | "Life"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
如您所见,published_books
列嵌套了 JSON 数据(一层)。 JSON 将动态 UUID 作为键,其值将是书籍详细信息,如 JSON。
我想在一定条件下搜索 books
并将那些书 JSON 数据单独提取到 return 作为结果。
我写的查询,
select JSON_EXTRACT(published_books, '$.*') from authors
where JSON_CONTAINS(published_books->'$.*.language', '"English"')
and JSON_CONTAINS(published_books->'$.*.tags', '["Social"]');
此查询执行搜索并 return 整个 published_books
JSON。但我只想要那些书 JSON。
预期的结果,
result
--------
"17e9bf8f": {
"name": "Book 1",
"tags": [
"self Help",
"Social"
],
"language": "English",
"release_date": "2017-05-01"
}
-----------
"8e8b2470": {
"name": "Book 6",
"tags": [
"Social",
"Life"
],
"language": "English",
"release_date": "2017-05-01"
}
您正在向后处理任务。
在您插入数据时进行提取。插入少量表格(作者、书籍、标签,也许还有更多)并在它们之间建立关系。 此数据库中不需要JSON。
结果是一个易于查询且快速的数据库。但是,它需要学习 RDBMS 和 SQL.
当数据是随机数据的集合时,JSON 很有用。您的 JSON 非常规则,因此 data 非常适合 RDBMS 技术。在这种情况下,JSON 只是一种序列化数据的标准方法。但不应该用于查询。
尚无 JSON 函数可以使用类似 "WHERE" 的逻辑过滤文档或数组的元素。
但这是一些使用JSON数据的人可能想做的任务,所以MySQL提供的解决方案是使用JSON_TABLE() function转换JSON 将文档转换成一种格式,就像您以正常方式存储数据一样 table。然后您可以对返回的字段使用标准的 SQL WHERE 子句。
在MySQL5.7中不能使用此功能,但如果升级到MySQL8.0就可以使用。
select authors.id, authors.name, books.* from authors,
json_table(published_books, '$.*'
columns(
bookid for ordinality,
name text path '$.name',
tags json path '$.tags',
language text path '$.language',
release_date date path '$.release_date')
) as books
where books.language = 'English'
and json_search(tags, 'one', 'Social') is not null;
+----+-------+--------+--------+-------------------------+----------+--------------+
| id | name | bookid | name | tags | language | release_date |
+----+-------+--------+--------+-------------------------+----------+--------------+
| 1 | Tina | 1 | Book 1 | ["self Help", "Social"] | English | 2017-05-01 |
| 3 | Keith | 2 | Book 6 | ["Social", "Life"] | English | 2017-05-01 |
+----+-------+--------+--------+-------------------------+----------+--------------+
请注意,嵌套的 JSON 数组仍然难以使用,即使使用 JSON_TABLE()
。在此示例中,我将 tags
公开为 JSON 数组,然后使用 JSON_SEARCH()
查找所需的标签。
我同意 Rick James 的观点——您不妨将数据存储在规范化的 table 和列中。您认为使用 JSON 会节省一些工作,但事实并非如此。将数据存储为单个 JSON 文档而不是跨多个 table 的多行可能会更方便,但您只需再次解开 JSON 即可查询它你想要的方式。
此外,如果将数据存储在JSON中,则每次要查询数据时,都必须解决这种JSON_TABLE()
表达式。 与正常存储数据相比,这将使您在持续的基础上做更多的工作。
坦率地说,我还没有在 Stack Overflow 上看到关于将 JSON 与 MySQL 一起使用的问题,该问题不会得出将数据存储在关系 table 中的结论如果数据结构不需要变化,这比使用 JSON 更好。
我有一个 MySQL table authors
列 id
、name
和 published_books
。在此,published_books
是 JSON 列。使用示例数据,
id | name | published_books
-----------------------------------------------------------------------
1 | Tina | {
| | "17e9bf8f": {
| | "name": "Book 1",
| | "tags": [
| | "self Help",
| | "Social"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 2",
| | "tags": [
| | "Inspirational"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
2 | John | {
| | "8e8b2470": {
| | "name": "Book 4",
| | "tags": [
| | "Social"
| | ],
| | "language": "Tamil",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
3 | Keith | {
| | "17e9bf8f": {
| | "name": "Book 5",
| | "tags": [
| | "Comedy"
| | ],
| | "language": "French",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 6",
| | "tags": [
| | "Social",
| | "Life"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
如您所见,published_books
列嵌套了 JSON 数据(一层)。 JSON 将动态 UUID 作为键,其值将是书籍详细信息,如 JSON。
我想在一定条件下搜索 books
并将那些书 JSON 数据单独提取到 return 作为结果。
我写的查询,
select JSON_EXTRACT(published_books, '$.*') from authors
where JSON_CONTAINS(published_books->'$.*.language', '"English"')
and JSON_CONTAINS(published_books->'$.*.tags', '["Social"]');
此查询执行搜索并 return 整个 published_books
JSON。但我只想要那些书 JSON。
预期的结果,
result
--------
"17e9bf8f": {
"name": "Book 1",
"tags": [
"self Help",
"Social"
],
"language": "English",
"release_date": "2017-05-01"
}
-----------
"8e8b2470": {
"name": "Book 6",
"tags": [
"Social",
"Life"
],
"language": "English",
"release_date": "2017-05-01"
}
您正在向后处理任务。
在您插入数据时进行提取。插入少量表格(作者、书籍、标签,也许还有更多)并在它们之间建立关系。 此数据库中不需要JSON。
结果是一个易于查询且快速的数据库。但是,它需要学习 RDBMS 和 SQL.
当数据是随机数据的集合时,JSON 很有用。您的 JSON 非常规则,因此 data 非常适合 RDBMS 技术。在这种情况下,JSON 只是一种序列化数据的标准方法。但不应该用于查询。
尚无 JSON 函数可以使用类似 "WHERE" 的逻辑过滤文档或数组的元素。
但这是一些使用JSON数据的人可能想做的任务,所以MySQL提供的解决方案是使用JSON_TABLE() function转换JSON 将文档转换成一种格式,就像您以正常方式存储数据一样 table。然后您可以对返回的字段使用标准的 SQL WHERE 子句。
在MySQL5.7中不能使用此功能,但如果升级到MySQL8.0就可以使用。
select authors.id, authors.name, books.* from authors,
json_table(published_books, '$.*'
columns(
bookid for ordinality,
name text path '$.name',
tags json path '$.tags',
language text path '$.language',
release_date date path '$.release_date')
) as books
where books.language = 'English'
and json_search(tags, 'one', 'Social') is not null;
+----+-------+--------+--------+-------------------------+----------+--------------+
| id | name | bookid | name | tags | language | release_date |
+----+-------+--------+--------+-------------------------+----------+--------------+
| 1 | Tina | 1 | Book 1 | ["self Help", "Social"] | English | 2017-05-01 |
| 3 | Keith | 2 | Book 6 | ["Social", "Life"] | English | 2017-05-01 |
+----+-------+--------+--------+-------------------------+----------+--------------+
请注意,嵌套的 JSON 数组仍然难以使用,即使使用 JSON_TABLE()
。在此示例中,我将 tags
公开为 JSON 数组,然后使用 JSON_SEARCH()
查找所需的标签。
我同意 Rick James 的观点——您不妨将数据存储在规范化的 table 和列中。您认为使用 JSON 会节省一些工作,但事实并非如此。将数据存储为单个 JSON 文档而不是跨多个 table 的多行可能会更方便,但您只需再次解开 JSON 即可查询它你想要的方式。
此外,如果将数据存储在JSON中,则每次要查询数据时,都必须解决这种JSON_TABLE()
表达式。 与正常存储数据相比,这将使您在持续的基础上做更多的工作。
坦率地说,我还没有在 Stack Overflow 上看到关于将 JSON 与 MySQL 一起使用的问题,该问题不会得出将数据存储在关系 table 中的结论如果数据结构不需要变化,这比使用 JSON 更好。