如何在 MySQL table 中找到搜索字符串的所有变体(重音等)?

How to find all variations (accented, etc) of a searched string in MySQL table?

我有一个很大的 MySQLInnoDB table,它在 utf8mb4_unicode_ci 中保存数据。我有几乎所有基于拉丁字母的语言的记录。我可以轻松地搜索带有重音字符的单词并找到具有不同变体的结果 (accented/not-accented),但土耳其语存在问题。当您指定包含大 I 字母的单词时,基本 LIKE 关键字在 SQL 行中不起作用。我希望看到所有包含该字母小写版本的单词(无点 i)。

因此,I在英语中是 i,但在土耳其语中是 dotless i。 (ı)

SELECT * FROM words WHERE word LIKE 'SIR'字不带sır字。它只带来 sir 个词,但它们都存在于同一个 table.

你遇到过这样的问题吗? SQL如何解决?

更新: SELECT * FROM words WHERE word LIKE 'SIR' COLLATE utf8mb4_turkish_ci returns sır 但不是 sir。尽管这可以解决一些问题,但不幸的是,从这个查询到 return 需要 23 秒而不是 0.00003 秒(没有 COLLATE 关键字)

这是一般 unicode 文本处理的已知棘手问题。您所能做的就是对具有不同形式 i 的单词使用 OR 或使用正则表达式模式。

索引还是扫描?

在您的示例中,我假设 word 已编入索引? table 相当大?在这种情况下,索引对于查找匹配 指定排序规则 的行非常有用。任何其他排序规则(您使用 COLLATE ... 的情况)需要忽略索引并扫描 整个 table(慢)。

使用 REGEXP 需要完整的 table 扫描。
即时执行 REPLACE(...) 需要完整的 table 扫描。

因此,假设有 "too many" 行可以进行完整的 table 扫描,没有简单的方法可以搜索 sırsir 任意归类。让我们寻找另一种方式...

首先,让我们看一些整理案例

在大多数 utf8 归类中,包括 utf8_unicode_ci,I=i=Ì=Í=Í=È=Ï=ì=í=í=î=ï=Ī=ī=Ç=į=İ
在 utf8_turkish_ci 中,I=ı,但它们出现在 i=Ì=Í=Í=È=Ï=ì=í=í=î=ï=Ī=ī=Į=į=İ 之前(因此,解释了你的部分问题)。
大多数其他 utf8 归类将 ı 视为介于 i 和 j 之间。
utf8_general_ci 略有不同:I=i=Ì=Í=Í=È=Ï=ì=í=í=î=ï=Ī=ī=Į=į=İ=ı
utf8_icelandic_ci 将一些带重音符号的 i 视为不同的字母:I=i=Ì=È=Ï=ì=î=ï=Ī=ī=Į=į=İ,但 Í=Í=í=í 介于两者之间I 和 J。那个人也在 Z 之后对这些进行排序: Ä=Æ=ä=æ Ö=Ø=ö=ø Å=å

我的Reference

另一个问题:重音字母 可以 显示为两个 utf8 字符 - 字母,然后是 "non-spacing mark"

那么,怎么办??

计划 A:构建您自己的归类。这需要一些工作,但并非不可能。这将是最佳的,为您提供最佳性能。正如我们将在下面看到的,utf8_unicode_520_ci 非常接近,可以作为一个起点。

计划 B:在您的 table 中添加另一列;我们称它为 wordx。它会有 word,但会去除高重音。然后索引 wordx 而不是 word。所以 word='sır' 的行会有 wordx='sir'.

计划 C:使用上面讨论的等效项,如果 "I" 从每个组中选择一种类型用于 table 中定义的排序规则,然后使用utf8_unicode_520_ciUNION:

( SELECT ... WHERE word = 'sir' )
UNION ALL
( SELECT ... WHERE word = 'sır' )

这应该包含 i 的所有风格。

哎呀,如果单词有多个不同的口音table字母怎么办?乍一看,这可能不是问题——所有 a 在 utf8_unicode_520_ci 中整理相等。浏览其余的字母,除了 ı 出现问题外,我没有看到任何其他内容。

下面是 utf8_unicode_520_ci 的有趣 等价物:

A=a=ª=À=Á=Á=Â=Ã=Ä=Å=à=á=á=â=ã=ä=å=Ā=ā=Ą=ą  Aa  ae=Æ=æ  az  B=b  C=c=Ç=ç=Č=č  ch  cz
D=d=Ð=ð=Ď=ď  dz  E=e=È=É=É=Ê=Ë=è=é=é=ê=ë=Ē=ē=Ĕ=ĕ=Ė=ė=Ę=ę=Ě=ě  F=f  fz  ƒ
G=g=Ğ=ğ=Ģ=ģ  gz  H=h  hz  I=i=Ì=Í=Í=Î=Ï=ì=í=í=î=ï=Ī=ī=Į=į=İ  ij=ij  iz  ı  J=j
K=k=Ķ=ķ  L=l=Ĺ=ĺ=Ļ=ļ=Ł=ł  lj=LJ=Lj=lj  ll  lz  M=m  N=n=Ñ=ñ=Ń=ń=Ņ=ņ=Ň=ň  nz
O=o=º=Ò=Ó=Ó=Ô=Õ=Ö=Ø=ò=ó=ó=ô=õ=ö=ø  oe=Œ=œ  oz  P=p  Q=q  R=r=Ř=ř  S=s=Ş=ş=Š=Š=š=š
sh  ss=ß  sz  T=t=Ť=ť  TM=tm=™  tz  U=u=Ù=Ú=Ú=Û=Ü=ù=ú=ú=û=ü=Ū=ū=Ů=ů=Ų=ų  ue  uz  V=v
W=w  X=x  Y=y=Ý=Ý=ý=ý=ÿ=Ÿ  yz  Z=z=Ž=Ž=ž=ž  zh  zz  Þ=þ  µ

如果您认为 ƒ 是重音字母,那么您可能也想处理它。

你的问题很有趣。