JSON タイプ

TiDB は、半構造化データの格納に役立つJSON (JavaScript Object Notation) データ型をサポートしています。 JSONデータ型には、文字列列にJSON形式の文字列を格納する場合と比較して、次の利点があります。

  • シリアル化には Binary 形式を使用します。内部フォーマットにより、 JSONのドキュメント要素への迅速な読み取りアクセスが可能になります。
  • JSON列に格納された JSON ドキュメントの自動検証。有効なドキュメントのみを保存できます。

JSON列は、他のバイナリ型の列と同様に直接インデックス付けされませんが、生成された列の形式でJSONドキュメントのフィールドにインデックスを付けることができます。

CREATE TABLE city ( id INT PRIMARY KEY, detail JSON, population INT AS (JSON_EXTRACT(detail, '$.population')), index index_name (population) ); INSERT INTO city (id,detail) VALUES (1, '{"name": "Beijing", "population": 100}'); SELECT id FROM city WHERE population >= 100;

詳細については、 JSON 関数および生成された列を参照してください。

制限

  • 現在、TiDB はJSONの関数を TiFlash にプッシュすることをサポートしていません。

  • TiDB は、JSON PATH での範囲選択構文の使用をサポートしていません。たとえば、TiDB で次の SQL ステートメントを実行すると、エラーが返されます。

    SELECT j->'$[1 to 2]' FROM t; SELECT j->'$[last]' FROM t;
  • v6.3.0 より前の TiDB Backup & Restore (BR) バージョンは、JSON 列を含むデータの回復をサポートしていません。 v6.3.0 より前の TiDB クラスターへの JSON 列を含むデータの回復をサポートする BR のバージョンはありません。

  • DATEDATETIME 、およびTIMEなどの非標準のJSONデータ型を含むデータを複製するために複製ツールを使用しないでください。

MySQL の互換性

  • BINARY型のデータを含む JSON 列を作成すると、MySQL は現在、データをSTRING型として誤ってラベル付けしますが、TiDB はそれをBINARY型として正しく処理します。

    CREATE TABLE test(a json); INSERT INTO test SELECT json_objectagg('a', b'01010101'); -- In TiDB, executing the following SQL statement returns `0, 0`. In MySQL, executing the following SQL statement returns `0, 1`. mysql> SELECT JSON_EXTRACT(JSON_OBJECT('a', b'01010101'), '$.a') = "base64:type15:VQ==" AS r1, JSON_EXTRACT(a, '$.a') = "base64:type15:VQ==" AS r2 FROM test; +------+------+ | r1 | r2 | +------+------+ | 0 | 0 | +------+------+ 1 row in set (0.01 sec)

    詳細については、問題#37443を参照してください。

  • データ型をENUMまたはSETからJSONに変換するとき、TiDB はデータ形式の正確性をチェックします。たとえば、TiDB で次の SQL ステートメントを実行すると、エラーが返されます。

    CREATE TABLE t(e ENUM('a')); INSERT INTO t VALUES ('a'); mysql> SELECT CAST(e AS JSON) FROM t; ERROR 3140 (22032): Invalid JSON text: The document root must not be followed by other values.

    詳細については、問題#9999を参照してください。

  • TiDB では、 ORDER BYを使用して JSON 配列または JSON オブジェクトをソートできます。

    MySQL でORDER BYを使用して JSON 配列または JSON オブジェクトを並べ替えると、MySQL は警告を返し、並べ替えの結果は比較操作の結果と一致しません。

    CREATE TABLE t(j JSON); INSERT INTO t VALUES ('[1,2,3,4]'); INSERT INTO t VALUES ('[5]'); mysql> SELECT j FROM t WHERE j < JSON_ARRAY(5); +--------------+ | j | +--------------+ | [1, 2, 3, 4] | +--------------+ 1 row in set (0.00 sec) -- In TiDB, executing the following SQL statement returns the correct sorting result. In MySQL, executing the following SQL statement returns the "This version of MySQL doesn't yet support 'sorting of non-scalar JSON values'." warning and the sorting result is inconsistent with the comparison result of `<`. mysql> SELECT j FROM t ORDER BY j; +--------------+ | j | +--------------+ | [1, 2, 3, 4] | | [5] | +--------------+ 2 rows in set (0.00 sec)

    詳細については、問題#37506を参照してください。

  • データを JSON 列に挿入すると、TiDB は暗黙的にデータの値をJSON型に変換します。

    CREATE TABLE t(col JSON); -- In TiDB, the following INSERT statement is executed successfully. In MySQL, executing the following INSERT statement returns the "Invalid JSON text" error. INSERT INTO t VALUES (3);

JSONデータ型の詳細については、 JSON関数および生成された列を参照してください。