保存布尔值并在搜索中保存CPU和内存的最佳解决方案

时间:2012-07-01 17:15:05

标签: mysql database database-design

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

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

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

有没有解决方案?

2 个答案:

答案 0 :(得分:1)

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

  1. 个别专栏
  2. 这反映在上面的示例中。优点是您可以将索引放在您最常用于查找的标记上。缺点是这将占用更多空间(因为可分配的最小列大小为1个字节。)

    但是,如果你的列名实际上是field_20,field_21等,那么这绝对不是你要走的路。编号列是您应该使用其他两种方法之一的标志。

    1. 位掩码
    2. 如上所述,您可以在单个整数列中存储多个值。 BIGINT列可以为您提供多达64个可能的标记。

      值类似于: UPDATE表SET flags = b'100'; UPDATE表SET flags = b'10000';

      然后该字段看起来像:10100

      这表示设置了两个标志值。要查询任何特定的标志值集,您可以执行

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

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

      1. 一对多的关系
      2. 这是你创建另一个表的地方,每一行都有它所链接的行的id,以及标志:

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

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

        然后你会在标志表中插入多行。

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

        对于性能比较,您可以阅读我就该主题撰写的博文: Set Performance Compare

        此外,当你问哪个是“最佳”时,这是非常主观问题。最好的是什么?这一切都取决于您的数据是什么样的,您的要求是什么以及您想如何查询它。

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

        索引只会在少数行设置该值时帮助您。如果表中的大多数行都有some_flag = true,那么mysql将忽略索引并改为执行全表扫描。

答案 1 :(得分:0)

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