# JSON 数据类型

MatrixOne 支持由 RFC 7159 定义的原生 JSON 数据类型，可以有效访问 JSON（JavaScript 对象表示法）文档中的数据。与将 JSON 格式的字符串存储在字符串列中相比，JSON 数据类型具有以下优势：

- 自动验证存储在 JSON 列中的 JSON 文档。无效的文档会产生报错。

- 自动优化存储格式。存储在 JSON 列中的 JSON 文档转换为允许对文档元素进行快速读取访问的内部格式。当服务器必须读取以这种二进制格式存储的 JSON 值时，不需要从文本中解析该值。二进制格式的结构使服务器能够直接通过键或数组索引查找子对象或嵌套值。

存储 JSON 文档所需的存储空间与 `BLOB` 或 `TEXT` 大致相同。

## JSON 的类型

JSON 类型有 JSON 数组和 JSON 对象。

- JSON 数组即包含由逗号分隔并包含在 `[]` 字符内的值列表，如：

```text
["abc", 10, null, true, false]
```

- JSON 对象包含一组键值对，由逗号分隔并包含在 `{}` 字符内，如：

```text
{"k1": "value", "k2": 10}
```

JSON 数组和对象可以包含标量值，即字符串或数字、JSON 空字面量或 JSON 布尔真或假字面量。JSON 对象中的键值必须是字符串。JSON 也允许时间（日期，日期时间）标量值。如：

```text
["12:18:29.000000", "2015-07-29", "2015-07-29 12:18:29.000000"]
```

在 JSON 数组元素和 JSON 对象键值中可嵌套，如：

```text
[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]]
{"k1": "value", "k2": [10, 20]}
```

## JSON 值的规范化

当一个字符串被解析为有效的 JSON 文档时，它也会被规范化。这表示意味着具有与稍后在文档中找到的键重复的键的成员，从左到右读取，将被丢弃。这意味着从左往右读取时，后面出现的重复的的键值将被忽略。

将值插入 JSON 列时执行规范化，如下所示：

```text
CREATE TABLE t1 (c1 JSON);
INSERT INTO t1 VALUES
     ('{"x": 17, "x": "red"}'),
     ('{"x": 17, "x": "red", "x": [3, 5, 7]}');

mysql> SELECT c1 FROM t1;
+------------------+
| c1               |
+------------------+
| {"x": "red"}     |
| {"x": [3, 5, 7]} |
+------------------+
2 rows in set (0.01 sec)
```
