如何解决在 MySQL 中存储人名的困境,同时保持可辨别性和对相似名称的搜索?
Posted
技术标签:
【中文标题】如何解决在 MySQL 中存储人名的困境,同时保持可辨别性和对相似名称的搜索?【英文标题】:How to solve Dilemma of storing human names in MySQL and keep both discriminability and a search for similar names? 【发布时间】:2011-10-15 16:10:23 【问题描述】:我被授予了一项漂亮的任务 ;-) 在 mysql 数据库中设计一些应该包含人名的表。
标准:
-
我只有全名。 (例如,前名、姓氏等没有分隔符)
存储应该是变音符号敏感的。 (以下名称代表不同的人)
“Voss”和“Voß”。 “乔尔”和“乔尔”。 “法郎”和“法郎”和“法郎”。搜索应该返回所有相似的名称到搜索字符串:例如:搜索“franc”应该返回 ["franc", "Franc", "Fránc"] 等等...(它会是如果搜索不仅会返回不区分变音符号的匹配项,而且还可能返回与搜索字符串部分匹配的发音相似的名称或名称,那就太棒了……)
我想将COLLATION utf8_bin
用于存储名称的列(声明为unique
)。这将满足第 2 点。但这会损害第 3 点。将列名声明为 unique
和 collation utf8_unicode_ci
满足第 3 点。但它会伤害第 2 点。
所以我的问题是:有没有办法解决这个任务并尊重所有标准?既然我不想重新发明***:有没有一种优雅的方式来处理数据库中的人名(及其搜索)? (遗憾的是,我无法将名称拆分为前名、姓氏和可选的中间名......)
编辑:
名称的数量约为一百万 (~1.000.000) 个条目。如果重要的话:我使用 python 作为脚本语言来填充数据库并稍后查询数据。
【问题讨论】:
你能指定表中可能有多少条记录吗?这会影响我建议的解决方案... @neokio:我想大约有一百万个条目。 (编辑了我的问题)。 您至少可以有一个包含组件名称(即分解为单词的名称)的伴随表吗?我花了大约一年的时间进行名称匹配。你不会相信你会遇到什么:名字中有数字,名字中有符号(像 *e 但发音为 Starry 的东西)。有目的的创造性拼写,几乎可以保证两个不同的数据输入人员输入的名字永远不会相同(如 Kaylie、K-Lee、Cayleigh 等名字的 30 多种变体)。太疯狂了。 @hatchet:我可以用空格分割全名。然后我会分解单词。这会有帮助吗? (如果我没听错的话……) 【参考方案1】:如果您可以将全名分解为组件“名称单词”并为每个组件存储一个语音编码(变音位或许多其他选择之一),这很有用。但是,您只需要名称词的概念,而不是专门将其分类为第一个或中间或最后一个,这很好,因为这些类别无论如何都不能很好地跨文化使用)。但是,如果您愿意,您可以稍后在排名中使用位置顺序信息,以便搜索“Paul Carl”比匹配“Carl Paul”更好地匹配“Paul Karl”。您需要注意可能需要存储某些名称单词的多个版本的模棱两可的标点符号。例如,Bre-Anna Heim 将被分解为名称单词“bre”“anna”“breanna”和“heim”。有时破折号像 Bre-Anna 一样无关紧要,但有时不像在 Sally-June 中那样”。Bre-Anna 从不只使用 Bre 或 Anna,但 Sally-June 有时可能只使用 Sally 或只使用 June。很难知道哪个,所以涵盖两种可能性。
您可以通过类似地分解和拼音编码您要搜索的全名来编写查询。例如,您的查询可以返回具有两个或多个组件名称拼音匹配的全名(如果搜索或源中只有一个名称,则返回一个)。这为您提供了一个完整名称的子集以供进一步考虑。您可以对它们进行简单的排名,甚至可以对这个子集进行距离匹配算法之类的操作,这在计算上对于整百万个名称来说太昂贵了。当我说距离匹配时,我指的是 Levenshtein 距离之类的在线算法。
(编辑)这样做的原因是处理类似以下名称的案件:Maria de los Angeles Gomez-Rodriguez。一位数据输入人员可能只输入 Maria Gomez。另一个可能会进入 Maria Gomez Rodriguez。还有一个可能会进入玛丽亚·安吉利斯·罗德里格斯。
【讨论】:
【参考方案2】:您可以在另一列中使用类似Metaphone(或Double Metaphone)的算法,以便尝试找到彼此“相似”的名称。您将不得不寻找了解德语 esset 字符的国际版本。
【讨论】:
以上是关于如何解决在 MySQL 中存储人名的困境,同时保持可辨别性和对相似名称的搜索?的主要内容,如果未能解决你的问题,请参考以下文章