首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用破折号的MySQL字符串匹配

使用破折号的MySQL字符串匹配
EN

Stack Overflow用户
提问于 2020-09-14 17:39:02
回答 1查看 146关注 0票数 4

我目前正在将数据从MySQL 5.6.41迁移到MySQL 8.0.21。总的来说,迁移过程相当顺利,有几个非常令人沮丧的小插曲。有一张桌子看起来像这样:

代码语言:javascript
运行
复制
CREATE TABLE `domains` (
`intDomainID` int(11) NOT NULL AUTO_INCREMENT,
`txtDomain` varchar(100) NOT NULL,
`dtDateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`blnTor` int(1) NOT NULL DEFAULT '0',
`txtTLD` varchar(100) NOT NULL,
PRIMARY KEY (`intDomainID`),
UNIQUE KEY `txtDomain` (`txtDomain`)
ENGINE=InnoDB AUTO_INCREMENT=10127897 DEFAULT CHARSET=utf8mb4;

创建模式已经完成,并且是由Workbench的“复制到剪贴板”-> "Create“函数创建的。

当我使用内置的Workbench导出/导入时,导入总是失败,并带有“txtDomain中的重复值”(在这里解释)错误,这很奇怪,因为原始表在该字段上有一个唯一的键约束,所以不能重复,并且我确认了它作为副本找到的值在原始数据库中不是重复的。

然后使用SELECT ... INTO OUTFILE转储表,将文件移到新服务器,并执行LOAD DATE INFILE。同样的“txtDomain中的重复值”错误也失败了。

然后,我删除了唯一的键约束,并重新做了LOAD DATE INFILE。这起作用了,数据就在那里。但是,由于“重复”,我不能返回唯一的键约束。我调查发现:

MySQL 5.6.41上的查询结果:

MySQL 8.0.21上的查询结果:

现在,怎么回事?表定义、数据库、表和字段字符集/排序规则是相同的。我需要拿回唯一的密钥约束..。

为什么http://d­­eepdot35wv­­m­eyd5.onion:80 == http://d­­ee-p---dot35w-v­­m­eyd5.onion:80

如果有帮助,我的导出命令:

代码语言:javascript
运行
复制
SELECT * INTO OUTFILE 'S:\\temp\\domains.txt'
  FIELDS TERMINATED BY ',' 
  OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  FROM domains;

我的进口命令:

代码语言:javascript
运行
复制
LOAD DATA INFILE 'E:\\DB Backup\\ServerMigration\\domains.txt' 
INTO TABLE domains
  FIELDS TERMINATED BY ',' 
  OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n';

排序规则:旧服务器: utf8_general_ci --我不记得接触过这个值-- New : utf8mb4_0900_ai_ci --我没有碰这个值-- DB旧/新是一样的: utf8mb4_0900_ai_ci表旧/新是一样的: utf8mb4_0900_ai_ci

这是原始TXT文件在文件系统上的样子:

注意,如果我将屏幕截图中的一个URL粘贴到这里,它将神奇地变成“正确”值,而不需要破折号:即:http://deepdot35w­­v­­­m­­­eyd5.onion:80

Note2:使用Notepad++,如果我将常规的“破折号”转换为HEX,就会得到"2D“。然而,如果我转换一个从URL,是造成麻烦,我得到HEX "C2AD“。看来我是在处理一个奇怪的unicode字符而不是破折号?

Note3:如果有人想要一个小的示例文件,那么它就是:https://www.dropbox.com/s/1ssbl95t2jgn2xy/domains_small.zip

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-14 19:14:38

所讨论的字符是U+00AD“软连字符”--一个不可打印的字符,用于向单词内的一个可能的连字符发出信号。

在新设置(带有默认排序规则设置的MySQL 8.0 )上,所使用的排序规则似乎与旧设置(默认排序规则设置为MySQL 5.7 )处理这些字符的方式不同:

比较中,这些不可打印的字符现在被忽略了。

你可以用这个简单的小提琴来测试不同之处。比较在5.6中为0,在MySQL 8.0 -> https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=a9bd0bf7de815dc14a886c5069bd1a0f中为"1“。

请注意,当未显式指定SQL花键时,它也使用默认排序规则配置。

您可以通过为txtDomain列设置二进制UTF-8排序规则来解决这一问题,这实际上是您想要的技术字符串:

代码语言:javascript
运行
复制
CREATE TABLE `domains` (
  `intDomainID` int(11) NOT NULL AUTO_INCREMENT,
  `txtDomain` varchar(100) NOT NULL 
      CHARACTER SET utf8mb4
      COLLATE utf8mb4_binary_ci,
  `dtDateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `blnTor` int(1) NOT NULL DEFAULT '0',
  `txtTLD` varchar(100) NOT NULL,
  PRIMARY KEY (`intDomainID`),
  UNIQUE KEY `txtDomain` (`txtDomain`)
) ENGINE=InnoDB AUTO_INCREMENT=10127897 DEFAULT CHARSET=utf8mb4;

更新:事实证明,排序规则在旧的(5.6)和新的( 8.0 )设置之间一定是不同的,因为utf8mb4_0900_ai_ci是在MySQL 8.0中引入的。旧的排序规则一定是utf8mb4_general_ci,在应用时,它也在MySQL 8.0中显示了所需的行为。

但是,无论如何,您应该使用二进制排序规则来处理技术字符串,比如URL。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63889274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档