我被授予了漂亮的任务;-)在MySQL数据库中设计一些应该保留人名的表。
标准:
存储应该是变音符号敏感的。 (以下名称代表不同的人)
搜索应该将所有相似的名称返回到搜索字符串:例如:搜索“franc”应该返回[“franc”,“Franc”,“Fránc”]等等...(这将是如果搜索不仅会返回diacritice不敏感的匹配,而且可能会返回与搜索字符串部分匹配的类似声音名称或名称,那真是太棒了...)
我想使用COLLATION utf8_bin
作为列(声明为unique
),我将在其中存储名称。这将满足第2点。但这将伤害第三点。使用unique
将列名称声明为collation utf8_unicode_ci
可以满足第3点的要求,但这会对第2点产生影响。
所以我的问题是:有没有办法解决这个任务并尊重所有标准?因为我不想重新发明轮子:是否有一种优雅的方式来处理数据库中的人名(及其搜索)? (可悲的是,我没有把名字分成名字,姓氏和可选中间名的可能性......)
名称的数量是一百万(~1.000.000)。如果重要的话:我使用python作为脚本语言来填充数据库并稍后查询数据。
答案 0 :(得分:2)
有用的是,如果您可以将全名分解为组件“名称单词”,并为每个单词存储语音编码(metaphone或许多其他选项之一)。你只需要名字的概念,而不是特别将它分类为第一个或中间或最后一个,这很好,因为这些类别无论如何都不能很好地适用于各种文化)。但是如果你愿意,你可以在排名后面使用位置订单信息,这样搜索“Paul Carl”比匹配“Carl Paul”更能匹配“Paul Karl”。您需要注意可能需要存储某些名称字的多个版本的模糊标点符号。例如,Bre-Anna Heim将被分为“bre”“anna”“breanna”和“heim”这两个名字。有时破折号与Bre-Anna无关,但有时候不像Sally-June那样。“Bre-Anna从不使用Bre或Anna,但是Sally-June可能只使用Sally或者有时只使用6月。很难知道哪个,所以涵盖两种可能性。
您可以通过类似地分解和语音编码您要搜索的全名来编写查询。例如,您的查询可以返回具有两个或更多组件名称拼音匹配的全名(如果搜索或源中只有一个名称,则返回一个)。这为您提供了要进一步考虑的全名子集。您可以对它们进行简单的排序,甚至可以对此子集执行类似距离匹配算法的操作,这对于整个百万个名称而言计算成本太高。当我说距离匹配时,我说的是Levenshtein距离之类的在线算法。
(编辑)这样做的原因是处理如下名称:Maria de los Angeles Gomez-Rodriguez。一个数据录入人员可能只是进入Maria Gomez。另一个人可能会进入Maria Gomez Rodriguez。还有一个人可能会进入Maria Angeles Rodrigus。
答案 1 :(得分:1)
您可以在另一列中使用Metaphone(或Double Metaphone)等算法,以便您可以尝试查找彼此“相似”的名称。您将不得不寻找一个了解德国esset角色的国际版本。