MySQL 8 忽略整数长度

MySQL 8 ignoring integer lengths

我在 Docker 容器中有一个 MySQL 8.0.19 运行 并使用 InnoDB 引擎。我注意到 table 整数字段长度被忽略了。

无论运行 CREATE 或 ALTER 查询

,整数数据类型都会出现问题
CREATE TABLE `test` (
  `id` int DEFAULT NULL,
  `text_field` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `decimal_field` decimal(6,2) DEFAULT NULL,
  `int_field` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

长度在我的 MySQL 客户端 (Navicat) 中显示为 0,但如果使用 SHOW FULL COLUMNS FROMtest;

在控制台中检查,也会出现同样的情况
mysql> SHOW FULL COLUMNS FROM `test`;
+---------------+--------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| Field         | Type         | Collation          | Null | Key | Default | Extra | Privileges                      | Comment |
+---------------+--------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| id            | int          | NULL               | YES  |     | NULL    |       | select,insert,update,references |         |
| text_field    | varchar(20)  | utf8mb4_unicode_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| decimal_field | decimal(6,2) | NULL               | YES  |     | NULL    |       | select,insert,update,references |         |
| int_field     | int          | NULL               | YES  |     | NULL    |       | select,insert,update,references |         |
+---------------+--------------+--------------------+------+-----+---------+-------+---------------------------------+---------+

Type 列应该为两个整数字段显示 int(11),但事实并非如此。

这是否与我的 MySQL 设置中的某些内容有关,如果是,则必须更改哪个变量?

这是 MySQL 8.0.19 release notes 中记录的更改:

Display width specification for integer data types was deprecated in MySQL 8.0.17, and now statements that include data type definitions in their output no longer show the display width for integer types, with these exceptions:

  • The type is TINYINT(1). MySQL Connectors make the assumption that TINYINT(1) columns originated as BOOLEAN columns; this exception enables them to continue to make that assumption.

  • The type includes the ZEROFILL attribute.

This change applies to tables, views, and stored routines, and affects the output from SHOW CREATE and DESCRIBE statements, and from INFORMATION_SCHEMA tables.

For DESCRIBE statements and INFORMATION_SCHEMA queries, output is unaffected for objects created in previous MySQL 8.0 versions because information already stored in the data dictionary remains unchanged. This exception does not apply for upgrades from MySQL 5.7 to 8.0, for which all data dictionary information is re-created such that data type definitions do not include display width. (Bug #30556657, Bug #97680)

整数列的"length"没有任何意义。 int(11) 的列与 int(2)int(40) 相同。它们都是固定大小的 32 位整数数据类型。它们支持相同的最小值和最大值。

整数列的 "length" 多年来一直是 MySQL 的一个令人困惑的特性。这只是一个影响显示宽度的提示,而不是存储或值的范围。实际上,只有当您使用 ZEROFILL 选项时才有意义。

mysql> create table t ( i1 int(6) zerofill, i2 int(12) zerofill );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t set i1 = 123, i2 = 123;
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+--------+--------------+
| i1     | i2           |
+--------+--------------+
| 000123 | 000000000123 |
+--------+--------------+
1 row in set (0.00 sec)

因此,误导性整数 "length" 现在已被弃用和删除,这是一件好事。多年来,它引起了混乱。

我可以确认已将 AWS RDS 升级到 MySQL 8.0.19,您现在可以使用 Navicat 正确同步。

但是,请注意!!

更新 id 列时,如果设置了 auto_increment,Navicat 会移除 auto_increment 以更改长度,然后在最后重新应用它。这会导致 auto_increment 列重新分配 ids 是顺序的!

ALTER TABLE `database`.`table` MODIFY COLUMN `id` mediumint(0) NOT NULL FIRST;
...
...
ALTER TABLE `database`.`table` MODIFY COLUMN `id` mediumint(0) NOT NULL AUTO_INCREMENT;

如果您正在使用 table 关系并且没有正确设置外键,这将破坏您的数据库!

此外,如果您的 auto_increment 列中的 ID 号为零或更小,这将导致以下错误:

Result: 1062 - ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'table.PRIMARY'

为避免上述情况,您需要手动将每个 table 的 id 长度更改为 0,然后在尝试使用 Navicat 同步功能之前保存更改。当使用 Navicat 保存更改时,这将自动将任何其他 int 列长度更改为 0。

在尝试应用到任何生产数据库之前,请确保您在数据库副本上彻底测试了您的更改。