如何从mysql中检索JSON数据?

pan*_*dge 23 mysql sql

我有以下表格和他们的关系.我将json数据存储在client_services表中.他们是否可以使用mysql查询检索JSON值.喜欢:

SELECT getJson("quota") as quota,
       client_id
FROM client_services
WHERE service_id = 1;     
Run Code Online (Sandbox Code Playgroud)

要么

我可以进一步规范化client_services表吗?

服务:

+----+-----------------------+--------------------------------------------------------+
| id | name                  | description                                            |
+----+-----------------------+--------------------------------------------------------+
|  1 | MailBox               |                                                        |
|  2 | SMS                   |                                                        |
|  3 | FTP                   |                                                        |
+----+-----------------------+--------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

service_features:

+----+------------+----------------------------------+------------------------+
| id | service_id | name                             | description            |
+----+------------+----------------------------------+------------------------+
| 10 |          1 | Forwarding                       | Forward Mail           |
| 11 |          1 | Archive                          | Archive Mail           |
| 12 |          1 | WebMail                          | NULL                   |
| 13 |          1 | IMAP                             | NULL                   |
| 14 |          2 | Web SMS                          | NULL                   |
+----+------------+----------------------------------+------------------------+
Run Code Online (Sandbox Code Playgroud)

client_services:

+-----+-----------+------------+-------------------------------------------------------------------------------------------+
| id  | client_id | service_id | service_values                                                                            |
+-----+-----------+------------+-------------------------------------------------------------------------------------------+
| 100 |      1000 |          1 |{ "quota": 100000,"free_quota":20000,"total_accounts":200,"data_transfer":1000000}         |
| 101 |      1000 |          2 |{ "quota": 200 }                                                                           |
| 102 |      1000 |          3 |{ "data_transfer":1000000}                                                                 |
| 103 |      1001 |          1 |{ "quota": 1000000,"free_quota":2000,"total_accounts":200,"data_transfer":1000000}         |
| 104 |      1001 |          2 |{ "quota": 500 }                                                                           |
| 105 |      1002 |          2 |{ "quota": 600 }                                                                           |
+-----+-----------+------------+-------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

client_feature_mappers:

+-----+-------------------+--------------------+-----------+
| id  | client_service_id | service_feature_id | client_id |
+-----+-------------------+--------------------+-----------+
|10000|                100|                 10 |       1000|
|10001|                100|                 11 |       1000|
|10002|                100|                 12 |       1000|
|10003|                100|                 13 |       1000|
|10004|                101|                 14 |       1000|
|10005|                103|                 10 |       1001|
|10006|                101|                 11 |       1001|
|10007|                101|                 12 |       1001|
|10008|                101|                 13 |       1001|
|10009|                105|                 14 |       1002|
+-----+-------------------+--------------------+-----------+
Run Code Online (Sandbox Code Playgroud)

tik*_*ika 47

由于很多人亲自向我提出这个问题,我想我会给这个答案第二次修改.这里有一个要点,它包含完整的SQL,包括SELECT,Migration和View Creation以及一个实时sql小提琴 (不能保证小提琴的可用性).

假设您有这样的表(名称:JSON_TABLE):

 ID   CITY        POPULATION_JSON_DATA
-----------------------------------------------------------------------
 1    LONDON      {"male" : 2000, "female" : 3000, "other" : 600}
 2    NEW YORK    {"male" : 4000, "female" : 5000, "other" : 500}
Run Code Online (Sandbox Code Playgroud)

要选择每个json字段,您可以执行以下操作:

SELECT 
    ID, CITY,
    json_extract(POPULATION_JSON_DATA, '$.male') AS POPL_MALE,
    json_extract(POPULATION_JSON_DATA, '$.female') AS POPL_FEMALE,
    json_extract(POPULATION_JSON_DATA, '$.other') AS POPL_OTHER
FROM JSON_TABLE;
Run Code Online (Sandbox Code Playgroud)

结果如下:

ID  CITY      POPL_MALE  POPL_FEMALE   POPL_OTHER 
-----------------------------------------------------------------
1   LONDON    2000       3000          600
2   NEW YORK  4000       5000          500
Run Code Online (Sandbox Code Playgroud)

根据您的数据大小和json复杂性,这可能是一项昂贵的操作.我建议用它

  1. 将表迁移到拆分数据库(参见附录2-B)
  2. 至少创建一个视图 (参见附录2-C)

注意:你可能有json 以双引号开头(字符串化):

"{"male" : 2000, "female" : 3000, "other" : 600}"
Run Code Online (Sandbox Code Playgroud)

在Ubuntu和Mac OSX Sierra上使用Mysql 5.7进行测试.

  • 我希望这个答案也应该有一些关于“json_extract”的信息 (3认同)
  • [_附加信息_] 在 MySQL **5.7.9 及更高版本**中,`->` 运算符(`column->path`)充当 `JSON_EXTRACT()` 函数的_别名_。更多信息和使用示例可以在[MySQL文档](https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#operator_json-column-path)中找到。 (2认同)

pdo*_*naj 5

您可以使用MySQL函数SUBSTRING_INDEX分解JSON字符串:

SELECT 
SUBSTRING_INDEX(
 SUBSTRING_INDEX(
  SUBSTRING_INDEX( service_values, 'quota', -1),
  '": ', -1),
 ' ', 1) AS quota,
client_id
FROM client_services
WHERE service_id=1;
Run Code Online (Sandbox Code Playgroud)