0

如果您希望在 select 语句上获得更高的查询性能和最小的内存损失,那么在数据库中插入布尔值的最佳解决方案是什么。

例如:我有一个包含 36 个字段的表,其中 30 个字段具有布尔值(零或一),我需要使用只有真实值的布尔字段来搜索记录。

SELECT * FROM `myTable`
WHERE 
    `field_5th` = 1 
    AND `field_12th` = 1 
    AND `field_20` = 1 
    AND `field_8` = 1

有什么解决办法吗?

4

2 回答 2

1

如果要存储布尔值或标志,基本上有三个选项:

  1. 单个列

这反映在您上面的示例中。优点是您将能够将索引放在您打算最常用于查找的标志上。缺点是这会占用更多空间(因为可以分配的最小列大小是 1 字节。)

但是,如果您的列名确实是 field_20、field_21 等。那么这绝对不是要走的路。编号的列表示您应该使用其他两种方法中的任何一种。

  1. 位掩码

如上所述,您可以将多个值存储在单个整数列中。BIGINT 列最多可为您提供 64 个可能的标志。

值将类似于: UPDATE table SET flags=b'100'; 更新表 SET flags=b'10000';

然后该字段看起来像:10100

这将表示设置了两个标志值。要查询任何特定的标志值集,你会做

SELECT flags FROM table WHERE flags & b'100';

这样做的好处是您的标志在空间上非常紧凑。缺点是您不能在字段上放置索引,这将有助于提高搜索特定标志的性能。

  1. 一对多关系

这是您创建另一个表的地方,那里的每一行都会有它链接到的行的 id 和标志:

CREATE TABLE main ( main_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, );

CREATE TABLE 标志( main_id INT UNSIGNED NOT NULL,名称 VARCHAR(16) );

然后,您将在标志表中插入多行。

优点是您可以使用索引进行查找,并且每行可以有任意数量的标志,而无需更改架构。这最适用于稀疏值,其中大多数行没有值集。如果每一行都需要定义所有标志,那么这不是很有效。

对于性能比较,您可以阅读我写的关于该主题的博客文章: 设置性能比较

此外,当您问哪个是“最佳”时,这是一个非常主观的问题。最擅长什么?这完全取决于您的数据是什么样的,您的需求是什么以及您希望如何查询它。

请记住,如果您想执行如下查询:SELECT * FROM table WHERE some_flag=true

仅当少数行设置了该值时,索引才会对您有所帮助。如果表中的大多数行的 some_flag=true,那么 mysql 将忽略索引并进行全表扫描。

于 2012-07-01T18:18:10.567 回答
0

您要查询多少行数据?您可以将布尔值存储在整数值中,并使用位运算来测试它们。它不可索引,但存储空间非常好。使用带有索引的 TINYINT 字段将选择一个索引来使用并从那里扫描。

于 2012-07-01T17:30:08.707 回答