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 ');
然后我从表条形码查询数据:
SELECT * FROM barcode WHERE `code` = 'abc ';
结果是:
+-----+-------+
|  id | code  |
+-----+-------+
|  1  |  abc  |
+-----+-------+
|  2  |  abc  |
+-----+-------+
但我希望结果集只有1条记录.我解决了:
SELECT * FROM barcode WHERE `code` = binary 'abc ';
结果是1条记录.但我正在使用NHibernate和MySQL从映射表生成查询.那么如何解决这个案子呢?
它没有其他解决方案.您可以指定单个比较,也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.这是这种做法的成功方式.
我假设您只想要一个结果,您可以使用LIMIT
SELECT * FROM barcode WHERE `code` = 'abc ' LIMIT 1;
要进行精确的字符串匹配,您可以使用Collation
 SELECT *
 FROM barcode
 WHERE code COLLATE utf8_bin = 'abc';