mysql從5.7開始已經支持JSON類型的字段。
支持的操作:添加,修改,置空,子key添加,子key重置,子key刪除,通過子key查找等。
但是這里和普通字段的修改和查找不同,涉及到一些JSON類型特有的函數。
具體參考:http://www.lnmp.cn/mysql-57-new-features-json.html
除了文章上面說的那些,還有幾個點需要注意:
1,JSON_CONTAINS函數
mysql> select * from test_json; +----+------------------------------------+---------+ | id | j | name | +----+------------------------------------+---------+ | 1 | {"url": "lnmp.cn", "name": "lnmp"} | | | 2 | NULL | |
執行sql:
mysql> select * from test_json where JSON_CONTAINS(j,'lnmp', '$.name'); ERROR 3141 (22032): Invalid JSON text in argument 2 to function json_contains: "Invalid value." at position 0. mysql> select * from test_json where JSON_CONTAINS(j,'"lnmp"', '$.name'); +----+------------------------------------+------+ | id | j | name | +----+------------------------------------+------+ | 1 | {"url": "lnmp.cn", "name": "lnmp"} | | +----+------------------------------------+------+ 1 row in set (0.00 sec)
JSON_CONTAINS(field, value, subkey)
第一個參數是字段名,第二個參數是查找的值,第三個參數是查找的子key。
這里的value有些限制條件,比如正整數1,需要寫成'1';如果是字符串"lnmp",要寫成'"lnmp"'。sql才是有效的。
2,幾種不同類型的空數組
JSON類型的數,可以支持null,{}, [],{'k':'v'},這些類型。
null:默認值就是null,可以單獨設置null;
{}:空的鍵值對,可以用cast('{}' as JSON)來設置;
[]:空的數組,可以用cast('[] as JSON')來設置,注意這里並不是集合的概念,里面的值是允許重復的;
{'k':'v'}:有鍵值對的數組,可以用cast來設置;
mysql> select * from test_json; +----+------------------------------------+---------+ | id | j | name | +----+------------------------------------+---------+ | 1 | {"url": "lnmp.cn", "name": "lnmp"} | | | 2 | NULL | | | 3 | {} | | | 4 | NULL | brother | | 5 | [100, 100, 200] | sister | +----+------------------------------------+---------+ 5 rows in set (0.00 sec)
3,應用中有很多場景,子key不是string,而是int類型,對於這樣的場景如何應對的?
A,添加子key為int類型的數據:
insert into test_json (j) values(cast('{0:"100",1:"200"}' as JSON)); ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json: "Missing a name for object member." at position 1.
由此可見,直接添加int型的子key是有問題的。
B,添加子key為string類型,但是值為數字型的數據:
mysql> insert into test_json (j) values(cast('{"0":"100","1":"200"}' as JSON)); Query OK, 1 row affected (0.01 sec) mysql> select * from test_json; +----+------------------------------------+---------+ | id | j | name | +----+------------------------------------+---------+ | 1 | {"url": "lnmp.cn", "name": "lnmp"} | | | 2 | NULL | | | 3 | {} | | | 4 | NULL | brother | | 5 | [100, 100, 200] | sister | | 6 | {"100": "100", "200": "200"} | | | 7 | {"0": "100", "1": "200"} | | +----+------------------------------------+---------+ 7 rows in set (0.00 sec)
結論:如果要添加數字型的子key,必須包含引號,int型轉成string型才可以。
C,按子key查找條目:
mysql> select * from test_json where JSON_CONTAINS(j, '"100"', '$."0"'); +----+--------------------------+------+ | id | j | name | +----+--------------------------+------+ | 7 | {"0": "100", "1": "200"} | | +----+--------------------------+------+ 1 row in set (0.00 sec)
這里有兩個點要注意,1是第二個參數必須是帶印號,2是第三個參數的鍵值名稱必須帶雙引號,而不是之前的'$.name'這樣的方式。
D,select中帶有子key:
mysql> select j->'$."0"' from test_json where id=7; +------------+ | j->'$."0"' | +------------+ | "100" | +------------+ 1 row in set (0.00 sec)
和C注意的點是一樣子的。