【问题标题】:SQL and fuzzy comparisonSQL和模糊比较
【发布时间】:2013-03-25 20:34:59
【问题描述】:

假设我们有一张 People 表(姓名、姓氏、地址、SSN 等)。

我们希望找到与指定人员 A“非常相似”的所有行。 我想对 A 和 People 表中的所有行进行某种模糊逻辑比较。将有多个模糊推理规则分别在多个列上工作(例如,3 个名称模糊规则,2 个姓氏规则,5 个地址规则)

问题是以下两种方法中哪一种更好?为什么?

  1. 将所有模糊规则实现为存储过程,并使用一个繁重的 SELECT 语句返回与 A“非常相似”的所有行。这种方法可能包括使用 soundex、sim metric 等。

  2. 实现一个或多个更简单的 SELECT 语句,返回不太准确的结果,与 A“相当相似”,然后将 A 与所有返回的行(外部数据库)进行模糊比较以获得“非常相似”的行。所以模糊比较会用我最喜欢的编程语言来实现。

Table People 最多应该有 500k 行,我希望每天进行大约 500-1000 次这样的查询。我使用 MySQL(但这还有待考虑)。

【问题讨论】:

  • 请说明您使用的是什么 rdbms。
  • 为什么不在你的选择中使用一个 case,如果它相似则返回 1,如果不相似则返回 0,然后对所有列求和。大于特定范围的应返回。似乎是解决您问题的简单方法。
  • @JesusZamora:问题在于,首先相似度的值可能是浮点数(例如 0.43),这就是我在谈论“模糊比较”的原因。第二个问题是计算这个相似度值相当繁重,我不知道哪种方法更优化。
  • @JesusZamora:模糊逻辑假设,不可能简单地说某事是真是假,因为有很多因素可能几乎是真的或不完全是假的。
  • 我刚刚找到this question,如果我理解正确,该问题的最佳答案显示了如何实施 2. 方法。

标签: mysql sql select fuzzy-logic fuzzy-comparison


【解决方案1】:

我真的不认为有一个明确的答案,因为它取决于问题中没有的信息。无论如何,评论太长了。

DBMS 擅长根据索引检索信息。除非它专门用于此特定目的(如@Adrian 所回答),否则让数据库服务器在繁重的计算中浪费时间是没有意义的。

因此,您的客户端应用程序应委托 DBMS 检索规则所需的信息。

如果计算量很小,都可以在服务器上完成。否则,将其拉入客户端系统。

第二种方法的缺点在于从服务器传输到客户端的数据量以及要建立的连接数。因此,通常它是服务器中计算和数据传输之间的折衷。根据模糊规则的特殊性来实现平衡。

编辑:我在评论中看到您几乎肯定必须在客户端中实现代码。在这种情况下,出于维护目的,您应该考虑一个额外的标准,代码局部性,即尝试将所有相关的代码放在一起,而不是在系统(和语言)之间传播。

【讨论】:

    【解决方案2】:

    我会说您最好使用简单的选择来获得最接近的匹配,而无需敲击数据库,然后在您的应用程序层中进行繁重的工作。我建议这个解决方案的原因是可扩展性:如果您在应用程序层进行繁重的工作,那么您的问题是 map-reduce 样式解决方案的完美用例,您可以跨节点分配相似性处理并获得结果比通过数据库更快地返回;另外,这样,您不会锁定数据库并减慢可能同时进行的任何其他操作。

    【讨论】:

    • 我认为这就是我将要实现的方式。但我仍然想知道这种方法是否有任何缺点或潜在风险。
    • 劣势将根据您的情况而定:如果您的数据库服务器通常比您的应用程序服务器有更多的未使用容量,您将希望将更多工作卸载到数据库服务器。如果它们在同一个盒子上,您必须以两种方式对其进行基准测试,以获得针对您的特定情况的最佳答案。
    【解决方案3】:

    由于您仍在考虑使用什么数据库,PostgreSQL 有 fuzzystrmatch 模块,该模块提供 Levenshtein 和 Soundex 函数。此外,您可能希望查看 pg_trm 模块,如here 所述。也许您也可以使用 soundex() 将索引放在列上,这样您就不必每次都计算它。 但是您似乎过早地进行了优化,因此我的建议是使用 pg 进行测试,然后想知道您是否需要优化,考虑到您几乎有两分钟的时间运行一个查询,您提供的数字确实看起来并不多。

    【讨论】:

    • 如果我决定使用第一种方法,使用来自fuzzystrmatch 的 levenshtein 和 soundex 函数听起来不错。但是我几乎可以肯定,我将不得不对至少一些指标(模糊规则)使用我自己的程序,因此使用这些模块并不能解决所有问题。无论如何,我仍然不确定在数据库中做所有事情是否更好以及为什么。
    • 更准确地说是要求。一天会有 500-1000 个查询,但应该尽快完成(比如不到一小时)
    • @running.t 在我的笔记本电脑上连续运行 100 万次 levenshtein() 函数不到半秒,diffrence() 是类似的,所以你至少不必担心这样做在数据库中。
    【解决方案4】:

    我会考虑的一个选项是在“People Talbe”中添加一列,即该人的 SoundEx 值。

    我已经使用

    完成了连接
    Select [Column}
    From People P 
        Inner join TableA A  on Soundex(A.ComarisonColumn) = P.SoundexColumn
    

    这将返回 TableA 中与 People Tables SoundEx 列中具有相同 SoundEx 值的任何内容。

    我没有在这种大小的表上使用过这种查询,但我认为尝试它没有问题。您还可以索引该 SoundExColumn 以帮助提高性能。

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      相关资源
      最近更新 更多