哪个MySQL数据类型用于存储布尔值

时间:2008-11-14 10:36:19

标签: mysql boolean sqldatatypes

由于MySQL似乎没有任何“布尔”数据类型,您是否“滥用”在MySQL中存储真/假信息?

特别是在写入和读取PHP脚本的上下文中。

随着时间的推移,我已经使用并看到了几种方法:

  • tinyint,包含值0/1,
  • 的varchar字段
  • 包含字符串'0'/'1'或'true'/'false'
  • 的varchar字段
  • 最后枚举包含两个选项'true'/'false'的字段。

以上都不是最佳选择。我更倾向于使用tinyint 0/1变体,因为PHP中的自动类型转换非常简单地给出了布尔值。

您使用哪种数据类型?有没有为布尔值设计的类型,我忽略了?您是否看到使用某种类型的优点/缺点?

13 个答案:

答案 0 :(得分:1162)

对于MySQL 5.0.3及更高版本,您可以使用BIT。手册说:

  

从MySQL 5.0.3开始,BIT数据类型用于存储位字段   值。一种BIT(M)允许存储M位值。 M可以范围   从1到64。

否则,根据MySQL手册,您可以使用bool和boolean,它们是tinyint(1)的别名:

  

Bool,Boolean:这些类型是TINYINT(1)的同义词。价值   零被认为是假的。非零   值被认为是真实的。

MySQL还声明:

  

我们打算实现完整的布尔值   类型处理,按照   标准SQL,在未来的MySQL中   释放。

参考文献:http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html

答案 1 :(得分:225)

BOOLBOOLEANTINYINT(1)的同义词。零是false,其他任何内容都是true。更多信息here

答案 2 :(得分:67)

这是一个优雅的解决方案,我非常欣赏,因为它使用零数据字节:

some_flag CHAR(0) DEFAULT NULL

要将其设置为true,请设置some_flag = ''并将其设置为false,设置some_flag = NULL

然后测试是否为true,检查some_flag IS NOT NULL,并测试是否为false,检查some_flag IS NULL

(这种方法在Jon Warren Lentz,Baron Schwartz和Arjen Lentz的“High Performance MySQL:Optimization,Backups,Replication,and More”中有描述。)

答案 3 :(得分:34)

这个问题已经得到解答,但我想我会投入0.02美元。我经常使用CHAR(0),其中''== true和NULL == false。

来自mysql docs

  当你需要一个只能使用的列时,

CHAR(0)也很不错   两个值:定义为CHAR(0)的列只占用一个NULL   bit,只能取值NULL和''(空字符串)。

答案 4 :(得分:32)

如果使用BOOLEAN类型,则将其别名为TINYINT(1)。如果你想使用标准化的SQL并且不介意该字段可能包含超出范围的值(基本上任何非0的都是'true'),这是最好的。

ENUM('False','True')将允许您使用SQL中的字符串,并且MySQL将在内部将字段存储为整数,其中'False'= 0并且'True'= 1基于顺序枚举已指定。

在MySQL 5+中,您可以使用BIT(1)字段来指示1位数字类型。我不相信这实际上在存储中使用了更少的空间,但是再次允许您将可能的值约束为1或0。

以上所有内容的使用量大致相同,因此最好选择最容易使用的存储空间。

答案 5 :(得分:18)

我使用TINYINT(1)来在Mysql中存储布尔值。

我不知道使用它是否有任何优势......但如果我没有错,mysql可以存储boolean(BOOL)并将其存储为tinyint(1)

http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html

答案 6 :(得分:16)

如果你有很多布尔字段,那么Bit只对各种字节选项(tinyint,enum,char(1))有利。一位字段仍占用一个完整字节。两个位字段适合同一个字节。三,四,五,六,七,八。之后他们开始填写下一个字节。最终节省的成本非常小,您应该关注数以千计的其他优化。除非您处理大量数据,否则这几个字节不会增加太多。如果您在PHP中使用bit,则需要对输入和输出的值进行类型转换。

答案 7 :(得分:13)

在MySQL实现位数据类型之前,如果您的处理真正按空间和/或时间(例如高容量事务),请为所有布尔变量创建一个名为bit_flags的TINYINT字段,并屏蔽和移位您在SQL查询中需要的布尔位。

例如,如果最左边的位代表你的bool字段,而最右边的7位代表什么,那么你的bit_flags字段将等于128(二进制10000000)。掩盖(隐藏)最右边的七个位(使用按位运算符&),并将第8位向右移动七个空格,最后以00000001结束。现在整个数字(在本例中为1)是你的价值。

SELECT (t.bit_flags & 128) >> 7 AS myBool FROM myTable t;

if bit_flags = 128 ==> 1 (true)
if bit_flags = 0 ==> 0 (false)

您可以在测试时运行这些语句

SELECT (128 & 128) >> 7;

SELECT (0 & 128) >> 7;

由于您有8位,因此一个字节可能有8个布尔变量。一些未来的程序员总是使用接下来的七位,所以你必须掩码。不要只是转移,否则你将来会为自己和他人制造地狱。确保你有MySQL做你的屏蔽和转移 - 这将比使用网络脚本语言(PHP,ASP等)做得快得多。另外,请确保在bit_flags字段的MySQL注释字段中添加注释。

在实施此方法时,您会发现这些网站很有用:

答案 8 :(得分:10)

我厌倦了尝试获得零,NULLS,并且''准确地围绕PHP,MySql和POST值循环,所以我只使用'是'和'否'。

这种方法完美无缺,无需特殊处理,不易察觉。

答案 9 :(得分:6)

参考此链接     Boolean datatype in Mysql,根据应用程序的用法,如果只想存储0或1,则bit(1)是更好的选择。

答案 10 :(得分:1)

在阅读完这里的答案后,我决定使用bit(1),是的,它在时空上有所改善,但是我改变主意一段时间后就不再使用了。再次。当使用准备好的语句,库等(php)时,这使我的开发变得非常复杂。

从那时起,我一直使用tinyint(1),看起来已经足够好了。

答案 11 :(得分:1)

您可以使用BOOL,BOOLEAN数据类型来存储布尔值。

这些类型是TINYINT(1)的同义词

但是,BIT(1)数据类型对于存储布尔值(true [1]或false [0])更有意义,但是在输出数据时,TINYINT(1)更易于使用,查询等,并实现MySQL与其他数据库之间的互操作性。您还可以检查this answer or thread

MySQL还将BOOL,BOOLEAN数据类型转换为TINYINT(1)。

此外,请阅读documentation

答案 12 :(得分:0)

由于MySQL(8.0.16)和MariaDB(10.2.1)都实现了CHECK约束,因此我现在将使用

label

您将只能存储bool_val TINYINT CHECK(bool_val IN(0,1)) 01,以及可以无误转换为NULL0的值例如1'1'0x00b'1' / TRUE

如果您不想允许NULL,请添加FALSE选项

NOT NULL

请注意,如果您使用bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1)) TINYINTTINYINT(1),实际上没有什么区别。

如果希望您的架构向上兼容,也可以使用TINYINT(123)BOOL

BOOLEAN

db<>fiddle demo