由于MySQL似乎没有任何“布尔”数据类型,您是否“滥用”在MySQL中存储真/假信息?
特别是在写入和读取PHP脚本的上下文中。
随着时间的推移,我已经使用并看到了几种方法:
以上都不是最佳选择。我更倾向于使用tinyint 0/1变体,因为PHP中的自动类型转换非常简单地给出了布尔值。
您使用哪种数据类型?有没有为布尔值设计的类型,我忽略了?您是否看到使用某种类型的优点/缺点?
答案 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)
BOOL
和BOOLEAN
是TINYINT(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。
当你需要一个只能使用的列时,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))
,0
或1
,以及可以无误转换为NULL
或0
的值例如1
,'1'
,0x00
或b'1'
/ TRUE
。
如果您不想允许NULL,请添加FALSE
选项
NOT NULL
请注意,如果您使用bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))
,TINYINT
或TINYINT(1)
,实际上没有什么区别。
如果希望您的架构向上兼容,也可以使用TINYINT(123)
或BOOL
BOOLEAN