SQL 数据类型与列约束速查

4 个速查板块 · 关联 2 款站内工具 · 数据最后核对 2026-10-10

INT 和 BIGINT 差多少、金额为什么不能用 FLOAT、VARCHAR 的长度到底是字符还是字节、DATETIME 和 TIMESTAMP 怎么选——建表前的类型功课一篇看全。

建表时选错类型,往往不是报错,而是埋雷:金额用了浮点型导致对账差几分钱,时间戳选错类型在 2038 年溢出,VARCHAR 长度理解错导致数据被截断。类型是表结构里影响最深远的决定,改动成本远高于加一个索引。

本篇以 MySQL 为主要口径(各数据库在细节上有差异,但整数与浮点的基本行为一致),把常用类型的关键数值和选型边界整理成表,配合可视化建表工具使用更顺手。

1整数类型

整数类型按存储字节数区分,有符号与无符号的取值范围大约差一倍。

类型字节数有符号范围无符号范围
TINYINT1−128 ~ 1270 ~ 255
SMALLINT2−32768 ~ 327670 ~ 65535
MEDIUMINT3−8388608 ~ 83886070 ~ 16777215
INT4约 ±21.47 亿0 ~ 约 42.95 亿
BIGINT8约 ±922 亿亿0 ~ 约 1844 亿亿

INT 的无符号上限约 42.95 亿,用作自增主键对绝大多数业务足够;日志、流水类写入量巨大的表可以直接上 BIGINT,避免日后痛苦的在线改表。

2小数、字符串与时间类型

金额必须用精确小数;字符串长度单位与时间类型的行为是最容易踩坑的两处。

类型关键参数要点
DECIMAL(M,D)M 总位数上限 65精确小数,金额、费率的唯一正确选择
FLOAT / DOUBLE单精度 4 字节 / 双精度 8 字节近似值,适合科学计算,不适合记账
CHAR(M)M 为 0 ~ 255定长,不足补空格,适合固定长度编码
VARCHAR(M)M 为字符数变长,实际占用还受行大小上限约束
TEXT 族TEXT 约 64KB 起大文本另存,不影响行内其他列的读取效率
DATE / TIME日期或仅时间DATE 范围 1000-01-01 ~ 9999-12-31
DATETIME不带时区换算存什么读什么,范围到 9999 年
TIMESTAMPUTC 存储、读时换算随会话时区变化,上限 2038-01-19

TIMESTAMP 会自动做时区换算,适合「全球同一时刻」的事件记录;DATETIME 适合「当地日历时间」如营业时间。跨时区系统混用两者是事故高发区。

3常用列约束

约束由数据库强制执行,比应用层校验更可靠,两者应同时存在。

PRIMARY KEY
主键,唯一且非空,一张表一个;常见做法是无符号 BIGINT 自增
NOT NULL
非空约束;空字符串与 NULL 语义不同,查询时 IS NULL 判断
UNIQUE
唯一约束,允许存在多个 NULL(MySQL 默认);常用于手机号、邮箱
DEFAULT
默认值;时间列常用 CURRENT_TIMESTAMP 作为默认
AUTO_INCREMENT
自增,仅用于整数列,一个表一个;用完主键可显式重设起点
FOREIGN KEY
外键,保证引用完整;高并发互联网业务常在应用层维护以降低锁开销

4三个高频误区

金额用 FLOAT
浮点是二进制近似,0.1 加不精确,对账必出错。金额用 DECIMAL,配整数分单位也可以
INT(11) 当长度限制
括号里的数字只是展示宽度提示,不影响存储范围,MySQL 8.0.17 起已弃用该写法
以为 VARCHAR(50) 是 50 字节
在 MySQL 4.1 之后 VARCHAR 长度按字符计,50 个汉字也能存;但行总长度仍受字节上限约束

关于「SQL 数据类型与列约束速查」的常见问题

金额字段为什么不能用 FLOAT 或 DOUBLE?

FLOAT 和 DOUBLE 按二进制浮点存储,无法精确表示大多数十进制小数,比如 0.1 在二进制里是无限循环小数,只能近似存储。单次运算误差极小,但金额要做大量加减聚合,误差会累积到分位以上,对账时就会出现差几块钱的情况。正确做法是用 DECIMAL 类型并指定精度,例如 DECIMAL(12,2) 表示总共 12 位、其中 2 位小数;另一种常见做法是用 BIGINT 存「分」,彻底绕开小数。两种方案都能保证精确,团队内统一口径即可。

DATETIME 和 TIMESTAMP 到底怎么选?

核心区别在时区行为:DATETIME 存的是字面时间,不换算,范围从 1000 年到 9999 年;TIMESTAMP 内部以 UTC 存储,读写时按会话时区自动换算,范围只到 2038 年初。如果业务是「某个全球统一时刻」,比如订单创建时间、日志时间,TIMESTAMP 的自动换算很方便;如果是「当地日历时间」,比如门店营业时间、生日,DATETIME 更直观。由于 2038 上限和时区隐式换算两个原因,现在很多团队统一用 DATETIME 并在应用层约定 UTC,这也是稳妥的选择。

自增主键用 INT 还是 BIGINT?

看写入量级。INT 无符号上限约 42.95 亿,对多数业务表绰绰有余;但日志、消息、流水这类持续大量写入的表,或者历史上经历过数据暴涨的表,直接用 BIGINT 更省心。虽然 BIGINT 多占 4 字节,在千万级表里总存储增量有限,而事后把已有数据的主键从 INT 改成 BIGINT 是一次代价很高的在线改表,还会波及所有引用该键的表。经验法则是:拿不准就 BIGINT,拿得准且确认写入量小再 INT。

内容标识:本页内容由人工智能辅助生成,并经人工核对与编辑。详见 人工智能生成内容标识说明。
内容说明:本页速查数据由本站自行整理,事实性内容以对应官方规范与文档为准,未复制第三方速查表或百科的表述。数据最后核对日期:2026-10-10。若发现错误或已更新的标准,欢迎通过页脚反馈入口告知。