[mysql]为什么对于整形计算的列一般使用bigint而不是int呢?

[mysql]为什么对于整形计算的列一般使用bigint而不是int呢?
最新回答
骑猪Δ追阳光

2023-02-22 03:41:54

在MySQL中,对于经常参与计算的整型列,推荐使用BIGINT而非INT的主要原因是为了避免数值溢出。以下是具体分析:

1. 数据范围差异
  • INT:32位有符号整数,范围为 -231 到 231-1(约±21.47亿)。
  • BIGINT:64位有符号整数,范围为 -2?3 到 2?3-1(约±9.22×101?)。

当计算结果可能超出INT范围时(例如连续乘法、累加或处理大数值),使用INT会导致溢出,返回错误结果或触发截断。而BIGINT能显著扩大安全计算的范围。

2. 计算场景的溢出风险
  • 示例:若某列存储值为23?(约10.7亿),执行乘以21?(1024)的操作后,结果为2??(约1.1万亿),远超INT上限(21.47亿)。此时若用INT存储,结果会溢出为负数或随机值。
  • 高频计算场景:如统计总和(SUM)、连乘(如复合增长率)、自增ID扩展等,均可能快速突破INT限制。
3. 《高性能MySQL》的建议解读

书中提到的建议(如使用BIGINT存储自增ID)与避免溢出直接相关:

  • 自增ID扩展性:即使当前数据量未达INT上限,未来增长可能溢出。直接使用BIGINT可免去后续迁移成本。
  • 计算中间结果:即使最终结果在INT范围内,中间计算步骤(如聚合函数)可能临时超出范围,导致错误。
4. 性能与存储权衡
  • 存储开销:BIGINT占8字节,INT占4字节。对大规模数据,BIGINT会多消耗50%存储空间。
  • 性能影响:64位运算可能比32位稍慢(但现代硬件优化后差异通常很小)。
  • 权衡建议

    若确定计算结果和中间值均不会超过INT范围(如仅存储年龄、小范围计数器),可用INT。

    若涉及大数计算、不确定未来增长或需绝对安全,优先选BIGINT。

5. 其他注意事项
  • 无符号整数:UNSIGNED INT可将上限提升至42.9亿,但无法解决乘法溢出问题(如231 * 2仍会溢出)。
  • 应用层校验:即使使用BIGINT,仍建议在应用层验证数据范围,避免逻辑错误。
总结

使用BIGINT的核心目的是为计算预留足够缓冲空间,避免因溢出导致的数据错误。在数据规模不明确或计算复杂度较高的场景下,这是一种更安全的选择。若能明确约束数据范围且性能敏感,可酌情使用INT。