我有以下表格及其关系。我将json数据存储在client_services表中。他们是否可以使用mysql查询检索JSON值。喜欢:
select getJson("quota") as quota, client_id from client_services where service_id =1;
OR
我可以进一步规范化client_services表吗?
服务:
+----+-----------------------+--------------------------------------------------------+
| id | name | description |
+----+-----------------------+--------------------------------------------------------+
| 1 | MailBox | |
| 2 | SMS | |
| 3 | FTP | |
+----+-----------------------+--------------------------------------------------------+
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 |
+----+------------+----------------------------------+------------------------+
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 } |
+-----+-----------+------------+-------------------------------------------------------------------------------------------+
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|
+-----+-------------------+--------------------+-----------+
答案 0 :(得分:39)
由于很多人亲自向我提出这个问题,我想我会给这个答案第二次修改。以下是a gist that has the complete SQL with SELECT, Migration and View Creation和a live sql fiddle (无法保证小提琴的可用性)。
让我们说你有这样的表(名字:JSON_TABLE):
ID CITY POPULATION_JSON_DATA
-----------------------------------------------------------------------
1 LONDON {"male" : 2000, "female" : 3000, "other" : 600}
2 NEW YORK {"male" : 4000, "female" : 5000, "other" : 500}
要选择每个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;
结果:
ID CITY POPL_MALE POPL_FEMALE POPL_OTHER
-----------------------------------------------------------------
1 LONDON 2000 3000 600
2 NEW YORK 4000 5000 500
根据您的数据大小和json复杂性,这可能是一项昂贵的操作。我建议将它用于
注意:你可能有json 以双引号开头 (字符串化):
"{"male" : 2000, "female" : 3000, "other" : 600}"
在Ubuntu和Mac OSX Sierra上使用Mysql 5.7进行测试。
答案 1 :(得分: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;
答案 2 :(得分:2)
首先,您应该知道上面的模型不是First Normal Form,这意味着每个字段中只有一个值。但是,此定义取决于您的应用程序查询处理需求。
所以,如果你想要的只是将一堆JSON数据放在一个字段中并按原样返回给应用程序,那就没关系了。您可以返回整个JSON数据,让应用程序选择它想要的JSON属性。
但是如果你有查询,就像在你的情况下,有标准或字段表达式查看JSON数据的细节,那么它绝对是一个禁忌。这将是查询复杂性和处理速度慢的噩梦。
您当然可以进一步规范化表以完全替换JSON数据结构。但是,如果您的应用程序需要灵活的模式,也许是使用NOSQL数据库的主要原因,但是您仍然坚持使用MySQL,有两种解决方案:
a)使用MySQL 5.6(或MariaDB v。??)进行NoSQL支持(我没有查看详细信息)http://www.computerworld.com/s/article/9236511/MySQL_5.6_tackles_NoSQL_competitors MariaDB的动态列:https://kb.askmonty.org/en/dynamic-columns/
b)在没有明确架构的情况下使用mysql,请参阅此处以获得一个非常完善的解决方案,该解决方案没有可伸缩性问题:http://backchannel.org/blog/friendfeed-schemaless-mysql
答案 3 :(得分:1)
是的,您绝对可以使用MySQL查询(使用JSON_EXTRACT()函数)来检索JSON值。
让我们获取包含json的表(此处为表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 } |
+-----+-----------+------------+-------------------------------------------------------------------------------------------+
要选择每个JSON字段,请运行以下查询:
SELECT
id, client_id, service_id,
json_extract(service_values, '$.quota') AS quota,
json_extract(service_values, '$.free_quota') AS free_quota,
json_extract(service_values, '$.total_accounts') AS total_accounts,
json_extract(service_values, '$.data_transfer') AS data_transfer
FROM client_services;
所以输出将是:
+-----+-----------+------------+-----------------------------------------------------+
| id | client_id | service_id | quota | free_quota | total_accounts | data_transfer|
+-----+-----------+------------+-----------------------------------------------------+
| 100 | 1000 | 1 | 100000 | 20000 | 200 | 1000000 |
| 101 | 1000 | 2 | 200 | null | null | null |
| 102 | 1000 | 3 | null | null | null | 1000000 |
| 103 | 1001 | 1 | 100000 | 2000 | 200 | 1000000 |
| 104 | 1001 | 2 | 500 | null | null | null |
| 105 | 1002 | 2 | 600 | null | null | null |
+-----+-----------+------------+-----------------------------------------------------+
希望这会有所帮助!
答案 4 :(得分:-1)
SET @a ='[{“ x”:2,“ y”:“ 8”},{“ x”:“ 3”,“ y”:“ 7”},{“ x”:“ 4 “,” y“:6}]';
选择* 从 JSON_TABLE( @一种, “ $ [*]”列( xval VARCHAR(100)路径“ $ .x”, yval VARCHAR(100)路径“ $ .y” ))AS jt1;