查询MySQL中的字符串比较精确

Tan*_*ong 7 mysql comparison collation

我在MySQL中创建了这样的表:

DROP TABLE IF EXISTS `barcode`;
CREATE TABLE `barcode` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(40) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


INSERT INTO `barcode` VALUES ('1', 'abc');

INSERT INTO `barcode` VALUES ('2', 'abc ');
Run Code Online (Sandbox Code Playgroud)

然后我从表条形码查询数据:

SELECT * FROM barcode WHERE `code` = 'abc ';
Run Code Online (Sandbox Code Playgroud)

结果是:

+-----+-------+
|  id | code  |
+-----+-------+
|  1  |  abc  |
+-----+-------+
|  2  |  abc  |
+-----+-------+
Run Code Online (Sandbox Code Playgroud)

但我希望结果集只有1条记录.我解决了:

SELECT * FROM barcode WHERE `code` = binary 'abc ';
Run Code Online (Sandbox Code Playgroud)

结果是1条记录.但我正在使用NHibernate和MySQL从映射表生成查询.那么如何解决这个案子呢?

Kai*_*aii 9

它没有其他解决方案.您可以指定单个比较,也binary可以将整个数据库连接设置为binary.(做SET NAMES binary,可能有其他副作用!)

基本上,'懒惰'比较是MySQL的一个特征,它是硬编码的.要禁用它(按需!),您可以使用binary比较,您显然已经做了.这不是"解决方法",而是真正的解决方案.

来自MySQL手册:

所有MySQL排序规则都是PADSPACE类型.这意味着MySQL中的所有CHAR和VARCHAR值都会进行比较,而不考虑任何尾随空格

当然,从用户的角度来看,还有很多其他的可能性来实现相同的结果,即:

  • WHERE field = 'abc ' AND CHAR_LENGTH(field) = CHAR_LENGTH('abc ')
  • WHERE field REGEXP 'abc[[:space:]]'

这些问题是它们有效地禁用了快速索引查找,因此您的查询始终会导致全表扫描.巨大的数据集可以带来很大的不同.

再次: PADSPACE默认为MySQL [VAR] CHAR比较.您可以(并且应该)使用禁用它BINARY.这是这种做法的成功方式.


Dar*_*ren 0

我假设您只想要一个结果,您可以使用LIMIT

SELECT * FROM barcode WHERE `code` = 'abc ' LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

要进行精确的字符串匹配,您可以使用Collation

 SELECT *
 FROM barcode
 WHERE code COLLATE utf8_bin = 'abc';
Run Code Online (Sandbox Code Playgroud)