MySql不接受布尔值作为其列数据类型

时间:2018-04-14 19:25:26

标签: mysql database boolean

我有一个Java程序,它以两种状态将数据存储在MySQL数据库中。为此我想使用BOOLEAN。但每当我输入BOOLEAN时,它就会变成TINYINT

还有其他方法可以将数据存储在两种状态吗?

3 个答案:

答案 0 :(得分:2)

MySQL使用TINYINT(1)来模仿布尔类型的行为,因此请确保使用TINYINT(1)作为列的数据类型,而不是TINYINT

或者,您可以使用BOOLBOOLEAN,它们都是TINYINT(1)的同义词。

同样,值TRUEFALSE只是MySQL中10的别名。

答案 1 :(得分:1)

MySQL没有本机布尔类型。

https://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html说:

  

BOOL,BOOLEAN

     

这些类型是TINYINT(1)的同义词。值为零被视为false。非零值被认为是真的:

这意味着"布尔" type仍然是一个8位有符号整数,the (1) syntax is not a size limit。它不会阻止列存储-128到127之间的整数值。由此决定不要存储这些值。

MySQL还支持BIT数据类型:https://dev.mysql.com/doc/refman/5.7/en/bit-type.html

MySQL JDBC驱动程序将BIT(1)转换为java.lang.Boolean。有关JDBC数据类型映射,请参阅https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-type-conversions.html

但BIT数据类型在其历史上有一些错误。我避免使用它。

无论如何,Bit可能不会节省任何空间,如果这是你所希望的。如果在表中连续定义了一堆BIT列,它们将被紧凑地存储,每个字节最多8列。但最小存储仍然是1个字节,所以如果你有1个BIT列,它仍然需要整整一个字节。

回答你的问题:

没有太多代码来测试它。

我创建了一个测试表,并在其中放入了一行值:

CREATE TABLE `foo` (
  `b` bool DEFAULT '1', /* this is a synonym for TINYINT(1) */
  `ti` tinyint DEFAULT '1',
  `tiu` tinyint unsigned DEFAULT '1',
  `si` smallintDEFAULT '1',
  `siu` smallint unsigned DEFAULT '1',
  `i` int DEFAULT '1',
  `iu` int unsigned DEFAULT '1',
  `bi` bigint DEFAULT '1',
  `biu` bigint unsigned DEFAULT '1'
);

INSERT INTO foo () VALUES ();

然后我调用了一些JDBC代码,并为每列使用getObject(),并要求它告诉我它返回的数据类型:

    stmt = conn.createStatement(); 
    rs = stmt.executeQuery("SELECT * FROM foo");
    while (rs.next()) {

        Object b = rs.getObject("b");
        System.out.println("b ("+b.getClass().getSimpleName()+"):\t" + b);

        Object ti = rs.getObject("ti");
        System.out.println("ti ("+ti.getClass().getSimpleName()+"):\t" + ti);

        Object tiu = rs.getObject("tiu");
        System.out.println("tiu ("+tiu.getClass().getSimpleName()+"):\t" + tiu);

        Object si = rs.getObject("si");
        System.out.println("si ("+si.getClass().getSimpleName()+"):\t" + si);

        Object siu = rs.getObject("siu");
        System.out.println("siu ("+siu.getClass().getSimpleName()+"):\t" + siu);

        Object i = rs.getObject("i");
        System.out.println("i ("+i.getClass().getSimpleName()+"):\t" + i);

        Object iu = rs.getObject("iu");
        System.out.println("iu ("+iu.getClass().getSimpleName()+"):\t" + iu);

        Object bi = rs.getObject("bi");
        System.out.println("bi ("+bi.getClass().getSimpleName()+"):\t" + bi);

        Object biu = rs.getObject("biu");
        System.out.println("biu ("+biu.getClass().getSimpleName()+"):\t" + biu);
    }

输出:

b (Boolean):    true
ti (Integer):   1
ti2 (Integer):  1
tiu (Integer):  1
si (Integer):   1
siu (Integer):  1
i (Integer):    1
iu (Long):  1
bi (Long):  1
biu (BigInteger):   1

我正在使用MySQL Connector / J 5.1.44进行测试。

所以似乎TINYINT(1)由JDBC驱动程序专门处理。它会自动将其转换为java.lang.Boolean。

同样,TINYINT(1)对MySQL中可能值的范围没有实际影响。它是一个8位有符号整数类型。但是JDBC驱动程序有特殊的代码来查找(1)长度选项,并使用它作为建议,使其转换为java.lang.Boolean。

java.lang.Integer可以使用无符号的32位INT,然后必须使用java.lang.Long来处理无符号的INT。然后是一个BigInteger用于未签名的BIGINT。 Java整数类型不是无符号的,因此要处理较大的无符号INT或BIGINT值,Java必须使用较大的Integer类型。

答案 2 :(得分:0)

BooleanTINYINT(1)mysql中的同义词,这意味着您可以互换使用它们而不会产生任何问题。