1、前 言
昨天下午,我让团队的一个小伙伴整理好他要发布到生产环境的 SQL 脚本,之后我提交 SQL 审核,结果一直报有一行错误,但却不提示具体是哪一行,反正结论是审核不通过,有点不爽。
我把他的 SQL 脚本打开检查,都是 DDL 语句,接着从语法、字段、是否有拼写错误、是否少了标点符号等方面检查了好几遍,都没发现问题。
在测试环境跑,运行起来一把过,结果 SQL 审核不通过,真是让人有点怀疑人生!
无奈地只能问 DBA 为什么了。DBA 回复让我将 is_deleted 字段的类型,由 bit(1) 改成 tinyint(1),我照做之后,果然成了。
为什么在 MySQL 中这个取值是 0 或者 1 的 is_deleted 字段,要改成 tinyint(1) ?用 bit(1) 不也可以吗?
当时我是有疑问的,不过我没问我们的 DBA ,因为那显得自己太拉跨了😂,虽然不是我写的脚本 。
既然有疑问,那总是要去解决的,下面一起来研究一下。
2、tinyint 与 bit 的区别
tinyint 和 bit 都是 MYSQL 中的一种数据类型,都可以在定义字段时使用。
tinyint
- 能存储 8 位值,也就是 1 个字节,有符号情况下,最大能存 127 的数值,如果超过,则报错
- 也可以用来存储布尔值也就是 0 或者 1 ,将类型定义为 tinyint(1)即可
bit
- 存储二进制值,也就是存 0 或者 1 ,如果存 2 及以上的值,就报错了
通过上面的简单介绍,可以知道,tinyint 占用的内存要比 bit 大,那为什么对于布尔值的处理,还是选择了 tinyint(1) 作为规范而不是 bit(1) ?
这里有个点要清楚,在 MYSQL 中是没有 boolean 类型这么一说的。对于 bit(1) 或者 tinyint(1) 类型的字段,传值 true 或者 false 会被映射成 1 或者 0 进行保存,例如下面的示例。
示例一
//java中定义的字段
private Boolean isDeleted;
//映射的 mysql 表字段
is_deleted bit(1) default b'0' commont '是否删除,0-否,1-是'
示例二
//java中定义的字段
private Boolean isDeleted;
//映射的 mysql 表字段
is_deleted tinyint(1) default 0 commont '是否删除,0-否,1-是'
说明:上面这两个示例的使用方式都没问题,都能运行,都可以。
那么,最终大多数公司在处理 MYSQL 中的布尔值字段时,选择将 tinyint(1) 作为规范而不是 bit(1) 的原因,个人觉得,大致有下面这么几点:
- MYSQL 本身默认将布尔值解释为 tinyint(1) 而不是 bit(1),这是最主要的原因
- tinyint(1) 不仅可以存 0 或者 1 ,也可以存 10 以下的整数,比如 2、3、4、5…9 而不会报错,利于字段多种状态类型的扩展
- 使用习惯问题导致,习惯了用 tinyint(1) ,所以公司的规范就是用 tinyint(1) ,没有道理可言
3、小 结
上面提到的两种使用方式没有对错之分,都可行,就看你所在公司对于这个点的规范是什么样了,我们按人家的规范走就好了,没必要死磕。