JSON 类型

JSON 类型可以存储 JSON 这种半结构化的数据,相比于直接将 JSON 存储为字符串,它的好处在于:

  1. 使用 Binary 格式进行序列化,对 JSON 的内部字段的查询、解析加快;
  2. 多了 JSON 合法性验证的步骤,只有合法的 JSON 文档才可以放入这个字段中;

JSON 字段本身上,并不能创建索引,但是可以对 JSON 文档中的某个子字段创建索引。例如:

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

使用限制

  • 暂不支持将 JSON 函数下推至 TiFlash。
  • TiDB Backup & Restore(BR)在 v6.3.0 版本对 JSON 列的数据的编码进行了修改。因此不建议使用 BR 恢复包含 JSON 列的数据到 v6.3.0 之前的 TiDB 集群。
  • 请勿使用任何同步工具同步非标准 JSON 类型(例如 DATE、DATETIME、TIME 等)的数据。

MySQL 兼容性

  • 当使用二进制类型数据创建 JSON 时,目前 MySQL 会将其误标记为 STRING 类型,而 TiDB 会保持正确的二进制类型。

    1. CREATE TABLE test(a json);
    2. INSERT INTO test SELECT json_objectagg('a', b'01010101');
    3. -- TiDB 中,执行以下 SQL 语句返回结果如下所示。在 MySQL 中,执行以下 SQL 语句的结果为 `0, 1`
    4. 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;
    5. +------+------+
    6. | r1 | r2 |
    7. +------+------+
    8. | 0 | 0 |
    9. +------+------+
    10. 1 row in set (0.01 sec)

    详情可见此 issue

  • 当将 ENUM 或 SET 数据类型转换为 JSON 时,TiDB 会检查其格式正确性。例如,当执行下面的 SQL 语句时,TiDB 中会报错:

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

    详情可见此 issue

  • TiDB 支持使用 ORDER BY 对 JSON Array 或 JSON Object 进行排序。

    当使用 ORDER BY 对 JSON Array 或 JSON Object 进行排序时,MySQL 会返回一个警告,且排序结果与比较运算结果不一致:

    1. CREATE TABLE t(j JSON);
    2. INSERT INTO t VALUES ('[1,2,3,4]');
    3. INSERT INTO t VALUES ('[5]');
    4. mysql> SELECT j FROM t WHERE j < JSON_ARRAY(5);
    5. +--------------+
    6. | j |
    7. +--------------+
    8. | [1, 2, 3, 4] |
    9. +--------------+
    10. 1 row in set (0.00 sec)
    11. -- TiDB 中,执行以下 SQL 语句返回结果如下所示。在 MySQL 中,执行以下 SQL 语句会返回警告 This version of MySQL doesn't yet support 'sorting of non-scalar JSON values'. ”,且排序结果与 `<` 比较结果不一致。
    12. mysql> SELECT j FROM t ORDER BY j;
    13. +--------------+
    14. | j |
    15. +--------------+
    16. | [1, 2, 3, 4] |
    17. | [5] |
    18. +--------------+
    19. 2 rows in set (0.00 sec)

    详情可见此 issue

  • 在 INSERT JSON 列时,TiDB 会将值隐式转换为 JSON:

    1. CREATE TABLE t(col JSON);
    2. -- TiDB 中,执行以下 INSERT 语句成功。在 MySQL 中,执行以下 INSERT 语句将返回 Invalid JSON text 错误。
    3. INSERT INTO t VALUES (3);

有关 JSON 的更多信息,可以参考 JSON 函数生成列