Skip to content

常见问题 ​

JSON ​

MySQL 8.0.16 JSON 字段键顺序问题 ​

问题描述 ​

在使用 MySQL 8.0.16 版本时,向 JSON 类型的字段插入 JSON 字符串后,发现存储后的 JSON 键顺序与插入前不一致。例如: 创建语句:

sql

```sql
drop table if exists telegram_channel_min;
CREATE TABLE telegram_channel_min (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  json JSON NOT NULL,
  `creator` varchar(64) NULL DEFAULT '',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
  `updater` varchar(64) NULL DEFAULT '',
  `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
  `deleted` smallint(6) NOT NULL DEFAULT 0,
  `tenant_id` bigint(20) NOT NULL DEFAULT 0
);
**插入前的 JSON:**

```json
{
  "identifier": -2094689180,
  "flags": 25184,
  "flags2": 0,
  "id": 1915354540,
  "title": "分享9",
  "username": "stddxgf",
  "photo": 935395612,
  "date": 1706613126,
  "access_hash": -5313070482928685903,
  "restriction_reason": [
    {
      "identifier": -797791052,
      "platform": "ios",
      "reason": "porn",
      "text": "This channel can’t be displayed because it was used to spread pornographic content."
    }
  ],
  "admin_rights": {
    "identifier": 1605510357,
    "flags": 6207
  }
}

查询后的 JSON:

json
{
  "id": 1915354540,
  "date": 1706613126,
  "flags": 25184,
  "photo": 935395612,
  "title": "分享9",
  "flags2": 0,
  "username": "stddxgf",
  "identifier": -2094689180,
  "access_hash": -5313070482928685903,
  "admin_rights": {
    "flags": 6207,
    "identifier": 1605510357
  },
  "restriction_reason": [
    {
      "text": "This channel can’t be displayed because it was used to spread pornographic content.",
      "reason": "porn",
      "platform": "ios",
      "identifier": -797791052
    }
  ]
}

原因分析 ​

  1. MySQL 版本限制:

    • MySQL 8.0.16 是 MySQL 8.0 系列的早期版本。尽管 MySQL 从 8.0 开始支持 JSON 类型并应保留键顺序,但早期版本可能存在未修复的 bug,导致 JSON 键顺序发生变化。

解决方案 ​

  1. 升级 MySQL 版本:

    • 建议将 MySQL 升级到最新的 8.0.x 版本(如 8.0.30 或更高),以确保所有与 JSON 相关的 bug 已被修复。
    • 升级步骤:
      • 备份数据:在升级前,务必备份现有数据库以防止数据丢失。
      • 阅读升级文档:参考 MySQL 官方升级指南 进行操作。
      • 测试升级:在测试环境中先行升级,确保应用程序与新版 MySQL 的兼容性。
  2. 临时解决方案:

    • 将 JSON 字段改为 TEXT 类型:
      • 如果升级 MySQL 版本不可行,可以考虑将 json 字段改为 TEXT 类型,以存储原始 JSON 字符串,确保键顺序保持不变。但这会失去 JSON 类型带来的查询和验证优势。

MIT Licensed