优先用 cast() 而非 convert(),因 cast 符合 sql 标准、行为稳定;convert 是 mysql 扩展语法,易解析歧义且类型名校验宽松,导致隐式错误;cast 强制使用 as 和官方支持类型(如 signed、date),更安全可控。

优先用 CAST(),别碰 CONVERT() 做类型转换——除非你要转字符集。
为什么 CAST() 是更安全的选择
MySQL 的 CAST() 遵循 SQL 标准,行为稳定;CONVERT(expr, type) 是 MySQL 扩展语法,在旧版本(如 5.7 某些补丁)里可能解析失败或返回意外结果。比如 CONVERT('123', SIGNED) 在部分实例中会被误认为是字符集转换调用,直接报错。
更关键的是:CAST() 的语法强制你写 AS,目标类型名也必须是 MySQL 官方白名单里的(如 SIGNED、DECIMAL(10,2)、DATE),而 CONVERT() 容易让你写错成 INT 或 FLOAT 这类非合法类型名,结果报 Truncated incorrect INTEGER value 却找不到原因。
-
CAST('123' AS SIGNED)✅ 合法 -
CAST('123' AS INT)❌ 报错,INT不在类型白名单中 -
CONVERT('123', INT)❌ 同样报错,但错误提示更模糊
CAST() 支持哪些目标类型?怎么选
不是所有常见类型名都能用。MySQL 只认这几个核心类型关键字:
-
CHAR(可带长度,如CHAR(20)) -
SIGNED(有符号整数,对应BIGINT范围) -
UNSIGNED(无符号整数) -
DECIMAL(M,D)(必须指定精度,如DECIMAL(10,2)) -
DATE、DATETIME、TIME BINARY
注意:CAST('05/01/2023' AS DATE) 不报错但返回 NULL;CAST('' AS SIGNED) 得 0,CAST('' AS DATE) 得 NULL——空字符串转数值和转日期逻辑不一致,得提前用 IFNULL() 或正则校验。
字符串转数值时的静默失败风险
MySQL 对非法输入不做报错,而是静默返回默认值,极易掩盖数据质量问题:
-
CAST('abc123' AS SIGNED)→0(不是错误,但业务上可能误判为“有效数字”) -
CAST('12.99' AS SIGNED)→12(小数部分直接截断,不四舍五入) -
CAST('12.99' AS DECIMAL(3,1))→13.0(精度溢出时自动进位,不是截断)
建议在 WHERE 或聚合前加过滤:WHERE price_str REGEXP '^[0-9]+(\.[0-9]{1,2})?$',再套 CAST()。
在 WHERE 和 ORDER BY 中用 CAST() 的性能陷阱
对字段加 CAST() 几乎必然让索引失效。例如:WHERE CAST(phone AS CHAR) LIKE '138%',即使 phone 是 BIGINT 且有索引,执行计划里 key 字段也会是 NULL。
替代方案只有两个:
- 建生成列 + 索引:
ALTER TABLE users ADD phone_str VARCHAR(20) STORED AS (CAST(phone AS CHAR)), ADD INDEX idx_phone_str (phone_str); - 日期分组优先用
DATE(created_at)而非CAST(created_at AS DATE),前者更容易被优化器识别为范围扫描
任何临时加 CAST() 的查询,上线前必须跑 EXPLAIN,重点看 key 是否命中、Extra 是否出现 Using filesort 或 Using temporary。











