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

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

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

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

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

我倾向于使用tinyint 0/1变体,因为PHP中的自动类型转换给我的布尔值相当简单。

那么你使用哪种数据类型?是否有一种我忽略的为布尔值设计的类型?使用这种或那种类型有什么优点/缺点吗?

993852 次浏览

我使用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。手册说:

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

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

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

MySQL还指出:

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

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

BOOLBOOLEANTINYINT(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

mysql文档

CHAR(0)也是相当不错的,当你需要一个列,只能采取两个值:定义为CHAR(0)NULL的列只占用一个位,只能取值NULL''(空字符串)。

在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个布尔变量。未来的一些程序员总是会使用接下来的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

然后为了测试true,检查some_flagIS NOT NULL,为了测试false,检查some_flagIS NULL

(此方法在Jon Warren Lentz、Baron Schwartz和Arjen Lentz的“高性能MySQL:优化、备份、复制等”中进行了描述。)

我厌倦了尝试获取零、NULLS和“准确地绕过PHP、MySql和POST值的循环,所以我只使用'Yes'和'No'。

这是完美的,不需要特殊的处理,这是不明显和容易做到的。

点击此链接MySQL中的布尔数据类型,根据应用程序的使用情况,如果只想存储0或1,则bit(1)是更好的选择。

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

从那时起,我总是使用tinyint(1),似乎足够好。

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

bool_val TINYINT CHECK(bool_val IN(0,1))

您将只能存储01NULL,以及可以转换为01的值,而不会出现'1'0x00b'1'TRUE/FALSE等错误。

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

bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))

请注意,如果您使用TINYINTTINYINT(1)TINYINT(123),实际上没有区别。

如果您希望架构向上兼容,也可以使用BOOLBOOLEAN

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)。

阅读留档