在一个字段上搜索二进制字符串

时间:2010-04-16 14:41:01

标签: mysql

我在一个表中有300个布尔字段,我正在尝试这样做:

一个字符串字段:

10000010000100100100100100010001

这是一个简单的方法来搜索这个字段,如:

select * from table where field  xor "10000010000100100100000000010001"

我正在尝试这个但是很长时间:

select * from test where mid(info,2,1) and mid(info,3,1)

:)帮助!!

3 个答案:

答案 0 :(得分:0)

来自书籍High Performance MySQL的引文:

  

如果您使用了整数,则可以按如下方式编写该示例:

mysql> SET @CAN_READ   := 1 << 0,
    -> @CAN_WRITE  := 1 << 1,
    -> @CAN_DELETE := 1 << 2;
mysql> CREATE TABLE acl (
    -> perms TINYINT UNSIGNED NOT NULL DEFAULT 0
    -> );
mysql> INSERT INTO acl(perms) VALUES(@CAN_READ + @CAN_DELETE);
mysql> SELECT perms FROM acl WHERE perms & @CAN_READ;
+-------+
| perms |
+-------+
|   5   |
+-------+

<强> UPD

如果所有字符串的长度都相同,那么在您的情况下可能会有一个解决方案(如果不是,我会感到惊讶):

select * from teste where info like '_______00001001001001001___1___1';

答案 1 :(得分:0)

如果您编写自己的外部函数并在那里进行比较,那么将bit掩码应用于除int之外的其他类型(如您的情况下的字符串)是可能的,但如果您不熟悉C语言本身的编程,这有点硬核。仅为其内部使用的int类型提供位掩码运算符。

编辑:或使用newtower提供的“LIKE”解决方案

请参阅其他类似主题:Is there a practical limit to the size of bit masks?

虽然在空间和速度方面有效,但这种解决问题的方法与具有300列的表具有相同的缺点。具有如此多列的表非常不灵活,添加和删除值需要更改表的结构,而不是数据。

虽然将其压缩到一个字段似乎可以解决问题,但它实际上使数据包含相同结构的更加不灵活的格式,因为您正在删除列:数据语义并且仅依赖于位置数据。对这种数据存储格式进行更改最终会非常耗费时间并且容易出错。

在我看来,如果你颠倒了你的问题并制作了一个包含你的布尔值的表而不是有很多列,你会做得更好。通常就是这种情况。 :)

改为使用JYelton提供的表结构,或者类似的东西,如果可能的话。

答案 2 :(得分:0)

如果可以的话,处理此问题的最佳方法是创建另一个表,该表将作为多对一链接到现有表,然后您可以使用select语句查找子表匹配中的所有记录父表的ID。在此示例中,新表将命名为 info (在列之后),而前一个表名为 parent

SELECT parent.*
FROM info
INNER JOIN parent
ON parent.id = info.parent_id
WHERE info.data IN ( 2, 3 ) // see note 1
GROUP BY parent.id
HAVING COUNT(*) = 2 // see note 2

注1:字符串中的位置现在是存储在新表中“数据”列中的整数。

注2:您需要指定上面指定的值数。

思考:此查询不会消除数据表中其他值匹配的父记录。