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

特别是在写入和读取 PHP 脚本的情况下。

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

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

以上似乎都不是最佳的。我更喜欢tinyint 0/1 变体,因为PHP 中的自动类型转换为我提供了相当简单的布尔值。

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

有帮助吗?

解决方案

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

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

否则,根据 MySQL 手册,您可以使用 bool 和 boolean,它们目前是别名 小整数(1):

布尔,布尔值:这些类型是同义词 天音(1).值 零被视为 false。非零 值被视为 true。

MySQL 还指出:

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

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

其他提示

BOOLBOOLEAN 是同义词 TINYINT(1). 。零是 false, ,其他的都是 true. 。更多信息 这里.

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

some_flag CHAR(0) DEFAULT NULL

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

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

(此方法在《高性能MySQL:优化、备份、复制等》,作者:Jon Warren Lentz、Baron Schwartz 和 Arjen Lentz。)

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

mysql 文档

当您需要一个只能接受的列时,CHAR(0) 也相当不错 两个值:定义为 CHAR(0) NULL 的列仅占用一个 位,并且只能接受值 NULL 和 ''(空字符串)。

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

ENUM('False', 'True') 将允许您在 SQL 中使用字符串,MySQL 将根据指定 Enum 的顺序在内部将字段存储为整数,其中 'False'=0 和 'True'=1 。

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

上述所有内容都将使用大约相同的存储量,因此最好选择您认为最容易使用的一个。

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

不知道用这个有没有什么好处...但如果我没记错的话,mysql可以存储布尔值(BOOL)并将其存储为tinyint(1)

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

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

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

例如,如果你的最左边的位代表你的 bool 字段,而最右边的 7 位代表什么,那么你的 bit_flags 字段将等于 128(二进制 10000000)。屏蔽(隐藏)最右边的七个位(使用按位运算符 &),并将第 8 位向右移动 7 个空格,最后得到 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;

ETC。

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

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

我厌倦了试图在 PHP、MySql 和 POST 值的循环中精确地获取零、NULL 和 '',所以我只使用 '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))

您将只能存储 0, 1 或者 NULL, ,以及可以转换为的值 0 或者 1 没有错误,如 '1', 0x00, b'1' 或者 TRUE/FALSE.

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

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

请注意,如果您使用,几乎没有区别 TINYINT, TINYINT(1) 或者 TINYINT(123).

如果您希望您的架构向上兼容,您还可以使用 BOOL 或者 BOOLEAN

bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))

db<>小提琴演示

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top