likes
comments
collection
share

谈谈bit(M) 和 tinyint(M)

作者站长头像
站长
· 阅读数 13

一、概述

tinyint(M) [unsigned] [zerofill]

  1. 数值类型,一个字节。带符号的范围是-128到127。无符号的范围是0到255。M默认为4。

  2. M指定并不是表示存储范围长度,对tinyint的存储范围是无影响的。M是针对在tinyint设定zerofill时,显示的最大宽度。在未设定zerofill时,无实际意义。

  3. 当M等于1时,在JDBC代码中,getObject()的情况下,会将tinyint(1)转换成boolean类型,且认为tinyint(1)是bit类型,大于等于1的数值认为是true

 谈谈bit(M) 和 tinyint(M)

当M大于1时,则正常表示整数,且类型是tinyint

 谈谈bit(M) 和 tinyint(M)

bit(M)

  1. 位字段类型,M表示每个值的位数,M的范围从1到64,M默认为1。

  2. M的大小限定了bit的数值的存储范围

    当M等于1时,bit类型只有一位,表示范围非1即0。

 谈谈bit(M) 和 tinyint(M)

此时在JDBC代码中,getObject()情况下,将bit(1)转成boolean类型:

 谈谈bit(M) 和 tinyint(M)

 谈谈bit(M) 和 tinyint(M)

当M等于3时,bit类型有三位,表示范围0~7

 谈谈bit(M) 和 tinyint(M)

当我们往里面插入b'1000'(即8)则会报错

 谈谈bit(M) 和 tinyint(M)

此时在JDBC中,getObject()情况下,将bit(3)转成Byte类型:

 谈谈bit(M) 和 tinyint(M)

 谈谈bit(M) 和 tinyint(M)

二、总结

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个状态.

 谈谈bit(M) 和 tinyint(M)

5、JDBC代码中,tinyint(1)和bit(1)在getInt()情况下,正常显示数值。

 谈谈bit(M) 和 tinyint(M)

三、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;
    }
}
​