由于MySQL似乎没有任何“布尔”数据类型,您“滥用”哪种数据类型在MySQL中存储真/假信息?
特别是在编写和读取PHP脚本的上下文中。
随着时间的推移,我使用并看到了几种方法:
我倾向于使用tinyint 0/1变体,因为PHP中的自动类型转换给我的布尔值相当简单。
那么你使用哪种数据类型?是否有一种我忽略的为布尔值设计的类型?使用这种或那种类型有什么优点/缺点吗?
我使用TINYINT(1)在MySQL中存储布尔值。
我不知道使用这个是否有任何好处……但如果我没有错,mysql可以存储布尔值(BOOL)并将其存储为tinyint(1)
http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html
对于MySQL 5.0.3及更高版本,您可以使用BIT。手册说:
BIT
从MySQL 5.0.3开始,BIT数据类型用于存储位字段值。一种BIT(M)类型可以存储M位值。M可以范围从1到64.
否则,根据MySQL手册,您可以使用BOOL或BOOLEAN,它们目前是tinyint(1)的别名:
BOOL
BOOLEAN
Bool, Boolean:这些类型是TINYINT(1)的同义词零被认为是假的。非零值为true。
MySQL还指出:
我们打算实现全布尔类型处理,按照标准SQL,在未来的MySQL释放。
参考文献:http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html
BOOL和BOOLEAN是TINYINT(1)的同义词。零是false,其他任何东西都是true。更多信息这里。
TINYINT(1)
false
true
如果您使用BOOLEAN类型,则别名为TINYINT(1)。如果您想使用标准化的SQL并且不介意该字段可能包含超出范围的值(基本上任何非0的值都将为“true”),这是最好的。
ENUM('False','True')将允许您使用SQL中的字符串,MySQL将在内部将字段存储为整数,其中'False'=0和'True'=1基于指定枚举的顺序。
在MySQL 5+中,您可以使用BIT(1)字段来指示1位数字类型。我不认为这实际上使用了更少的存储空间,但再次允许您将可能的值限制为1或0。
上述所有内容都将使用大致相同的存储量,因此最好选择您认为最容易使用的存储空间。
这个问题已经得到了回答,但我想我会投入我的0.02美元。我经常使用CHAR(0),其中'' == true and NULL == false。
CHAR(0)
'' == true and NULL == false
从mysql文档:
CHAR(0)也是相当不错的,当你需要一个列,只能采取两个值:定义为CHAR(0)NULL的列只占用一个位,只能取值NULL和''(空字符串)。
NULL
''
在MySQL实现位数据类型之前,如果您的处理确实需要空间和/或时间,例如大容量事务,请为所有布尔变量创建一个名为bit_flags的TINYINT字段,并屏蔽和移动您在SQL查询中所需的布尔位。
bit_flags
例如,如果您的最左边的位表示您的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个布尔变量。未来的一些程序员总是会使用接下来的7位,所以你必须掩码。不要只是移动,否则你将在未来为自己和他人创造地狱。确保你让MySQL做掩码和移动——这将比Web脚本语言(PHP、ASP等)做的快得多。此外,确保你在MySQL注释字段中为你的bit_flags字段放置注释。
在实现此方法时,您会发现这些站点很有用:
如果你有很多布尔字段,位只比各种字节选项(tinyint、enum、char(1))有优势。一位字段仍然占用一个完整的字节。两位字段适合同一个字节。三、四、五、六、七、八。然后他们开始填充下一个字节。最终节省的是如此之小,你应该关注数千个其他优化。除非你处理大量的数据,否则这几个字节加起来不会太多。如果你在PHP中使用bit,你需要对输入和输出的值进行类型转换。
这是一个优雅的解决方案,我非常欣赏,因为它使用零数据字节:
some_flag CHAR(0) DEFAULT NULL
要将其设置为true,请设置some_flag = '';要将其设置为false,请设置some_flag = NULL。
some_flag = ''
some_flag = NULL
然后为了测试true,检查some_flagIS NOT NULL,为了测试false,检查some_flagIS NULL。
IS NOT NULL
IS NULL
(此方法在Jon Warren Lentz、Baron Schwartz和Arjen Lentz的“高性能MySQL:优化、备份、复制等”中进行了描述。)
我厌倦了尝试获取零、NULLS和“准确地绕过PHP、MySql和POST值的循环,所以我只使用'Yes'和'No'。
这是完美的,不需要特殊的处理,这是不明显和容易做到的。
点击此链接MySQL中的布尔数据类型,根据应用程序的使用情况,如果只想存储0或1,则bit(1)是更好的选择。
在阅读了这里的答案后,我决定使用bit(1),是的,它在空间/时间上更好,但是一段时间后,我改变了主意,我再也不会使用它了。当使用准备好的语句、库等(php)时,它使我的开发变得非常复杂。
bit(1)
从那时起,我总是使用tinyint(1),似乎足够好。
tinyint(1)
由于MySQL(8.0.16)和MariaDB(10.2.1)都实现了CHECK约束,我现在将使用
bool_val TINYINT CHECK(bool_val IN(0,1))
您将只能存储0、1或NULL,以及可以转换为0或1的值,而不会出现'1'、0x00、b'1'或TRUE/FALSE等错误。
0
1
'1'
0x00
b'1'
TRUE
FALSE
如果您不想允许NULL,请添加NOT NULL选项
NOT NULL
bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))
请注意,如果您使用TINYINT、TINYINT(1)或TINYINT(123),实际上没有区别。
TINYINT
TINYINT(123)
如果您希望架构向上兼容,也可以使用BOOL或BOOLEAN
bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))
db<>小提琴演示
您可以使用BOOL、BOOLEAN数据类型来存储布尔值。
这些类型是TINYINT的同义词(1)
然而,BIT(1)数据类型更适合存储布尔值(true[1]或false[0]),但当您输出数据、查询等时,TINYINT(1)更容易使用,并实现MySQL和其他数据库之间的互操作性。您还可以选中这个答案或线程。
MySQL还将BOOL、BOOLEAN数据类型转换为TINYINT(1)。
阅读留档