将现有 MySQL 列更改为 JSON 数据类型
Posted
技术标签:
【中文标题】将现有 MySQL 列更改为 JSON 数据类型【英文标题】:Alter an existing MySQL column to a JSON data type 【发布时间】:2016-10-15 05:16:11 【问题描述】:我正在尝试将 mysql 列从 varchar(9000) NULL 更改为 MySQL 5.7 中的新 JSON 数据类型。该列包含有效的 JSON 字符串,但某些值为 null。当我尝试以下操作时:
alter table log modify request json
它失败并出现以下错误:
Invalid JSON text: "The document is empty." at position 0 in value for column '#sql-2f36_168a6.request'
但是,当我创建一个新列时:
alter table log add request_json json
然后插入相同的数据:
update log set request_json=json where request != ''
新的 request_json 列已更新。如何将现有列修改为 JSON 数据类型并保留 JSON 数据而不创建新列?
【问题讨论】:
你在NULL
和''
之间的专栏有什么不同?运行SELECT `log` FROM `request` WHERE JSON_VALID(`log`)=0\G
来检测那些可能导致问题的行。
我运行了您的查询,发现数百个具有空值或空白值。 NULL 对 json 数据类型无效吗?
所以在玩了一会儿之后,似乎 NULL 是有效的,但有一个空白值是无效的。这是真的吗?
【参考方案1】:
12.6 The JSON Data Type
...
自动验证存储在 JSON 列中的 JSON 文档。无效的文档会产生错误。...
mysql> SHOW CREATE TABLE `log`\G
*************************** 1. row ***************************
Table: log
Create Table: CREATE TABLE `log` (
`request` json DEFAULT NULL
) ENGINE=InnoDB
1 row in set (0,00 sec)
mysql> SELECT `request`, JSON_VALID(`request`)
-> FROM `log`;
+-----------------+-----------------------+
| request | JSON_VALID(`request`) |
+-----------------+-----------------------+
| "type": "bug" | 1 |
| NULL | NULL |
| NULL | NULL |
+-----------------+-----------------------+
3 rows in set (0,00 sec)
mysql> UPDATE `log`
-> SET `request` = ''
-> WHERE `request` IS NULL;
ERROR 3140 (22032): Invalid JSON text: "The document is empty." at position 0 in value for column 'log.request'.
试试:
mysql> DROP TABLE IF EXISTS `log`;
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE TABLE IF NOT EXISTS `log` (
-> `request` VARCHAR(9000) NULL
-> );
Query OK, 0 rows affected (0,01 sec)
mysql> INSERT INTO `log`
-> (`request`)
-> VALUES
-> ('"type": "bug"'),
-> (NULL),
-> ('');
Query OK, 3 rows affected (0,00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT `request`, JSON_VALID(`request`)
-> FROM `log`;
+-----------------+-----------------------+
| request | JSON_VALID(`request`) |
+-----------------+-----------------------+
| "type": "bug" | 1 |
| NULL | NULL |
| | 0 |
+-----------------+-----------------------+
3 rows in set (0,00 sec)
mysql> ALTER TABLE `log` MODIFY `request` JSON;
ERROR 3140 (22032): Invalid JSON text: "The document is empty." at position 0 in value for column '#sql-1bab_4.request'.
mysql> UPDATE `log`
-> SET `request` = NULL
-> WHERE `request` = '';
Query OK, 1 row affected (0,00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> ALTER TABLE `log` MODIFY `request` JSON;
Query OK, 3 rows affected (0,00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT `request`, JSON_VALID(`request`)
-> FROM `log`;
+-----------------+-----------------------+
| request | JSON_VALID(`request`) |
+-----------------+-----------------------+
| "type": "bug" | 1 |
| NULL | NULL |
| NULL | NULL |
+-----------------+-----------------------+
3 rows in set (0,00 sec)
mysql> SHOW CREATE TABLE `log`\G
*************************** 1. row ***************************
Table: log
Create Table: CREATE TABLE `log` (
`request` json DEFAULT NULL
) ENGINE=InnoDB
1 row in set (0,00 sec)
【讨论】:
以上是关于将现有 MySQL 列更改为 JSON 数据类型的主要内容,如果未能解决你的问题,请参考以下文章
MySQL:错误代码:1118 行大小太大(> 8126)。将某些列更改为 TEXT 或 BLOB
当主键列是mysql中不同表的外键时,如何将主键列更改为自动递增
PySpark DataFrame在使用explode之前将字符串的列更改为数组
Liquibase:使用带 H2 数据库的 modifyDataType 重构将 INT 自动增量列更改为 BIGINT