navicat 中“未签署”对应 sql 的 unsigned 关键字,勾选后需保存或执行 ddl 才生效;导出或迁移时必须核对 sql 是否含 unsigned,否则字段会变回有符号。
navicat 里设置无符号整数,不是勾选“无符号”就完事——你得确认它真生成了 int unsigned 这样的 sql,否则换环境或导出时字段会悄悄变回有符号。
Navicat 界面里的 “Unsigned” 实际对应什么?
中文版 Navicat 把 unsigned 翻译成“未签署”,位置通常在字段类型下方、zerofill 上方。但关键点在于:这个勾选框只是 GUI 表达,底层仍靠 SQL 定义生效。
- 建表时勾选“未签署”,Navicat 会自动生成类似
id INT(11) UNSIGNED的语句——这是有效的 - 如果用“设计表”修改已有字段,只勾选“未签署”却不点“保存”或没触发 DDL 重写,可能实际没执行
ALTER TABLE ... MODIFY COLUMN - 导出表结构时,务必检查 SQL 文件里该字段是否含
UNSIGNED关键字;若没有,说明 GUI 操作未落地
修改已有字段为 UNSIGNED 的正确姿势
不能只改属性开关,必须让 MySQL 重新解析并存储类型定义。
- 用 Navicat 的“设计表” → 选中字段 → 勾选“未签署” → 点“保存”(这步会触发
ALTER TABLE ... CHANGE COLUMN) - 或者直接在查询窗口手动执行:
ALTER TABLE `table_name` MODIFY COLUMN `column_name` INT UNSIGNED;
- 注意:如果原字段有负数默认值(如
DEFAULT -1),执行会报错,必须先删掉或改成非负值 - 如果字段是主键或被外键引用,
MODIFY COLUMN可能失败,需先删约束再加回来
PHP/Java 等应用层插入失败的常见原因
报错 Out of range value for column 很少是 Navicat 设置错了,更多是应用传了超限值或类型溢出。
- PHP 中
3000000000在 32 位环境下会被解释成负数(因为超过PHP_INT_MAX),再塞进INT UNSIGNED字段就会被拒 - 用
var_dump(PHP_INT_SIZE)确认是否 64 位;不是的话,避免用(int)强转大字符串,改用filter_var($str, FILTER_VALIDATE_INT)或保持字符串传参(PDO 支持) - Java + JPA 场景下,
BIGINT UNSIGNED应映射为BigInteger而非Long,否则超过9223372036854775807会溢出
真正容易被忽略的是:Navicat 的“未签署”开关只影响当前操作,不保证迁移、同步、备份还原时的一致性。只要涉及跨环境部署,必须人工核对建表 SQL 是否含 UNSIGNED,而不是依赖界面状态。











