谈谈bit(M) 和 tinyint(M)
一、概述
tinyint(M) [unsigned] [zerofill]
-
数值类型,一个字节。带符号的范围是-128到127。无符号的范围是0到255。M默认为4。
-
M指定并不是表示存储范围长度,对tinyint的存储范围是无影响的。M是针对在tinyint设定zerofill时,显示的最大宽度。在未设定zerofill时,无实际意义。
-
当M等于1时,在JDBC代码中,getObject()的情况下,会将tinyint(1)转换成boolean类型,且认为tinyint(1)是bit类型,大于等于1的数值认为是true
当M大于1时,则正常表示整数,且类型是tinyint
bit(M)
-
位字段类型,M表示每个值的位数,M的范围从1到64,M默认为1。
-
M的大小限定了bit的数值的存储范围
当M等于1时,bit类型只有一位,表示范围非1即0。
此时在JDBC代码中,getObject()情况下,将bit(1)转成boolean类型:
当M等于3时,bit类型有三位,表示范围0~7
当我们往里面插入b'1000'(即8)则会报错
此时在JDBC中,getObject()情况下,将bit(3)转成Byte类型:
二、总结
1、如上文所说,在JDBC代码中,tinyint(1)和bit(1)都可以作为boolean 类型的表达,mysql中默认是tinyint(1)。
2、tinyint中M只是针对zerofill情况下具有意义,对tinyint的存储范围不影响。bit中M的大小,对bit的存储范围是具有直接影响的。
3、tinyint是数值类型,存储较小的数值, 一般对应编辑语言里的小字典或枚举类型. 节省空间的同时, 避免存入超范围的值.
4、bit类似多用于存储状态. 如bit(1) 直接对应Java语言的布尔类型true和false. 如下图可见,bit在mysql数据库中以二进制的形式存储,更符合boolean类型的语义。用做状态保存时一个字段可以保存多至64个状态.
5、JDBC代码中,tinyint(1)和bit(1)在getInt()情况下,正常显示数值。
三、tinyint被转换成boolean类型的解决方案
1、推荐无特殊需求,设置tinyint(4)
2、在jdbcUrl中添加参数:tinyInt1isBit=false
四、boolean到底采用tinyint(1)还是bit(1)?
就我个人观点而言,tinyint(1)存储空间是一个字节,也就是8个bit,占用的空间更多。而bit(1)是位数据类型,只占用一个bit。bit(1)作为boolean类型更佳。
五、相关代码
创建数据库:
/** 测试 tinyint(M) **/
CREATE TABLE `test`(
`id` bigint(20) NOT NULL,
`tin_yint` tinyint(1) NOT NULL DEFAULT '2',
`bi_t` bit(1) NOT NULL DEFAULT b'0'
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='测试表';
JDBC代码:
package com.xxkj;
import java.sql.*;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws Exception {
Connection connection = getConnection();
PreparedStatement pstmt = connection.prepareStatement("select id, tin_yint,bi_t from test ");
ResultSet rs = pstmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
System.out.println("第" + i + "列type:" + metaData.getColumnTypeName(i + 1));
}
while (rs.next()) {
System.out.println("id:" + rs.getObject(1) + " 第二列Tinyint(1)ToObj:" + rs.getObject(2) + " 第三列Bit(1)ToObj:" + rs.getObject(3));
}
connection.close();
}
public static Connection getConnection() {
Connection conn = null;
try {
// 1. 创建MySQL驱动对象
Driver driver = new com.mysql.cj.jdbc.Driver();
// 2. 提供要连接的数据库,IP地址替换为远程地址或者localhost,数据库替换为项目所使用的数据库
// String url = "jdbc:mysql://localhost:3306/GiftManagement";
// tinyint(1) 不转成bit类型,即不会转成boolean类型
String url = "jdbc:mysql://localhost:3306/GiftManagement?tinyInt1isBit=false";
// 3. 提供连接时需要的用户名和密码
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "001122");
// 4. 获取连接
conn = driver.connect(url, info);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
转载自:https://juejin.cn/post/7153199617071382558