SQL - 两个长度不同字符串的相似度

8
我有一个产品的SQL Server表,每个产品都有一个在我们网站上公开的描述。我想要防止或者至少在描述过于相似时警告用户。每个产品的描述长度可能差别很大。
我想查询那些包含重复/相似文本段落/块的描述的产品。例如,字符串A有一堆独特的内容,但与字符串B共享相似/相同的段落。然而,我不确定哪种相似度算法最好使用:
- Levenshtein距离Jaro-Winler距离算法似乎只能很好地处理短字符串。 - 我不确定最长公共子序列算法是否能够很好地考虑到大的差异。即它似乎忽略了两个字符之间的潜在空格,找到任何相似的组合序列。

模糊哈希算法听起来像是我要找的,但我不只是要寻找有微小差异的重复内容。我还要寻找在唯一文本块内注入微小差异的重复内容。而且我不知道如何在SQL中实现模糊哈希。

SOUNDEX()DIFFERENCE()似乎使用了模糊哈希,但对于我的用例来说不够精确。

理想情况下,相似性SQL函数应该快速,但我可以将缓存的相似值存储在另一个表中,并安排定期更新的作业。

哪种算法/SQL(或CLR集成)实现最好以实现此目标?


你为什么要限制自己只在SQL中实现这个功能呢? - Yosi Dahari
好吧,我想它不一定非得用SQL。但是,我认为纯SQL实现会更高效。我可以潜在地使用.NET CLR集成,比如这个相似度库...但我没有SQL Server CLR集成的经验,而且我仍然不知道要使用什么算法。 - David Budiac
你可以尝试的一件事是,取出字符串中特定字母的实例,然后对这些字符串进行Levenshtein计算。例如,取出像“Lorem ipsum dolor sit amet”这样的文本中只有e和t的实例。结果字符串将是etet,你可以将其与另一个过滤后的字符串进行Levenshtein计算。显然需要一些调整,但希望你能理解这个想法。 - kevmo314
有趣。我猜剪掉字母表的大部分的目的是为了帮助匹配单段落吗? - David Budiac
@DavidBudiac 大概就是这样。一般的想法是,因为Levenshtein是O(n²)的,所以删掉n的75%可以使性能提高94%,我们希望利用这一点。我们也知道很多时候即使缺少字符,也可以插值单词,所以通过切割字符,我们生成了一个更像是文本签名而不是DEFLATE式压缩的压缩版本。这也滥用了我们永远不需要“解压”签名的事实。 :) - kevmo314
我曾经遇到过类似的问题,我能够在SQL 2016中使用新的STRING_SPLIT()函数,并比较一个记录中字段正文中重复的单词数量与其他记录。这相当复杂,在大规模情况下性能不佳,但给了我想要的结果。 - schizoid04
1个回答

4

我最近需要使用模糊字符串匹配来加入组名。
我试过了大约40种不同的算法,但没有一种能够很好地完成此任务,即使是组名只是因为一些拼写错误、缺少空格和偶尔添加了_mLF而不同。

因此,如果你尝试类似的事情,我强烈建议你立即停止,并将数据(在我的情况下是Excel文件)发送回用户进行更正,这是它应该存在的地方。

如果你只是对比较字符串感兴趣,这个链接可能正是你需要的:
http://anastasiosyal.com/POST/2009/01/11/18.ASPX

我发现Jaro-Winkler函数在我的情况下产生了最好的结果,但你可以自己测试。


是的,理想情况下我会告诉用户停止输入重复文本。但有些人仍然会这样做... 我需要能够事后发现内容是否重复/相似。那篇文章确实有所帮助。 - David Budiac
2
我也发现这个模糊搜索算法的性能相当不错:https://sites.google.com/site/sqlblindman/fuzzysearchalgorithm - David Budiac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接