7

我正在建立一个数据库,其中尾随空格对结果很重要。当我查询结果时,我发现

SELECT * where `field` = 'a ' 

当存在值为 'a' 的字段时返回结果。我希望尾随空格在结果集中很重要。我尝试过使用 Char、Varchar、Text 和 Blob。我会注意到这个字段是我的表的索引。

有人可以告诉我如何以使尾随(和/或前导)空格计数的方式进行查询吗?我是否需要以任何特殊方式格式化我的表格才能完成这项工作?

4

2 回答 2

5

这种行为是设计使然,不仅在 MySQL 中。

您可以使用以下方法在比较中解决它BINARY

mysql> select version(), 'a' = 'a ', BINARY 'a' = BINARY 'a ';
+-------------+------------+--------------------------+
| version()   | 'a' = 'a ' | BINARY 'a' = BINARY 'a ' |
+-------------+------------+--------------------------+
| 5.5.25a-log |          1 |                        0 |
+-------------+------------+--------------------------+
1 row in set (0.00 sec)

但不多。SELECT如果空格出现在搜索的用户输入中,这将帮助您处理s;但是如果你想实际输入空格结尾的信息,那将是一个问题(你不能同时拥有'a'和'a'的索引)。

也可以看看

比较需要考虑 varchar 中的尾随空格

您可以想象反转该列中的字符串,并在显示它们时将它们反转回来。当然,这会破坏基于该列的任何排序,但如果您只测试相等或子字符串的存在,它可能会起作用。前导空格确实很重要。

对于相等搜索,您还可以存储字符串的 base64 编码,它应该保持字典顺序(即 a 和 b 之间的顺序应该保持在 base64(a) 和 base64(b) 之间)。或者您可以在字符串上附加一个终止符(“\n”可能会很好并且不会出现在搜索中)。

最后,但这是有风险的,因为人类无法区分,您可以用 UTF8 char(49824) 替换空格:

mysql> select concat ('\'a', char(49824),'\'') AS tricked,
              concat ('\'a', ' '        ,'\'') as honest,
              concat ('\'a', char(49824),'\'') =
              concat ('\'a', ' '        ,'\'') as equals;

+---------+--------+--------+
| tricked | honest | equals |
+---------+--------+--------+
| 'a '    | 'a '   |      0 |
+---------+--------+--------+
1 row in set (0.00 sec)

这些行似乎相等,但事实并非如此。请注意,在 HTML 中,空格是空格,而 49824 是 (不间断空格)。这会影响来回转换 HTML 的函数,并且 nbsp 实际上是 UTF8 代码点意味着诚实字符串是两个字节,但被欺骗字符串的长度实际上是3

最后,您可以声明该列VARBINARY而不是VARCHAR,从而完全隐藏正在发生的事情。它看起来是最简单的解决方案,但我担心它可能会在几周或几个月后给你带来麻烦。

于 2012-09-22T10:41:44.233 回答
1

我在以下方面取得了成功,但我不确定这是否是一种不稳定的方法。

CREATE TEMPORARY TABLE test (
  PRIMARY KEY(id),
  id INT AUTO_INCREMENT,
  val VARCHAR(20)
);

INSERT INTO test VALUES
(NULL, 'a'),
(NULL, 'a '),
(NULL, 'a  '),
(NULL, 'a   ');

SELECT * FROM test
WHERE val LIKE 'a ';

输出

id  val
2   'a '

使用 WHERE val = 'a ' 将选择所有条目而不考虑尾随空格,但 LIKE 对我有用。

于 2012-09-22T10:59:58.787 回答