数据库主键为何不设为无符号类型?相关技术疑问求解
这个问题问得挺到位的——乍一看无符号INT做主键确实能把可用范围从 -2^31 到 2^31-1 扩展到 0 到 2^32-1,相当于直接翻倍了存储上限,但确实有些场景下,使用有符号INT作为主键会更合适,甚至是必要的:
历史遗留与兼容性考量
很多成熟系统从搭建初期就采用了有符号主键,后续如果要改成无符号,需要同步修改所有关联表的外键类型,还要处理跨系统对接的兼容性问题(比如依赖该数据的外部系统只支持有符号整数)。这种改动牵一发而动全身,测试和迁移成本极高,与其冒险,不如继续沿用原有类型。框架/ORM的默认行为与兼容性限制
部分ORM框架或开发工具的默认配置会生成有符号INT主键,如果开发者没有特意修改配置,就会自然沿用。更关键的是,有些编程语言(比如Java)的原生整数类型是有符号的,直接映射无符号INT时,超过2^31-1的值会被转换成负数,引发逻辑错误。为了避免这种语言层面的适配问题,团队可能会选择有符号INT。特殊业务逻辑需要负主键
虽然不算常见,但有些业务会用负主键标记特殊数据:比如临时测试数据、逻辑删除后保留的“幽灵”记录,或者需要和正常数据区分开的异常数据。这种情况下,有符号INT的负数范围就能派上用场,不用额外加字段来标识数据类型。数据库工具或中间件的支持限制
早期的一些数据库备份、同步工具或中间件,对无符号整数的支持不够完善,可能会出现数据转换异常、丢失等问题。为了避免这些工具层面的坑,很多团队会选择兼容性更好的有符号INT。团队约定与业务量级匹配
对大部分中小业务来说,有符号INT的上限(约21亿条记录)已经完全够用,这辈子都未必能触及。这种情况下,团队出于习惯或减少不必要改动的考虑,会继续使用有符号INT——毕竟改动虽小,但也要做测试,没有明确收益的事没必要折腾。
当然,如果你的业务有明确的海量数据增长预期,或者是从零搭建新系统,选择无符号INT做主键肯定是更优的选择。但上面这些场景,确实会让有符号INT成为更合适的选项。
内容的提问来源于stack exchange,提问作者Charlie Brumbaugh

