【问题标题】:Pattern comparing with mysql between two tables column两个表列之间与mysql的模式比较
【发布时间】:2012-11-05 05:08:17
【问题描述】:

一个简单的问题是PHP中的preg_match和mysql查询中的like是一样的吗?

主要问题:

考虑以下是我的两个表 table1 和 table2

表 1                                                                              表 2

+--------+-------------+ +--------+------ ------------------------------------+ |身份证 |型号 | |身份证 |型号 | +--------+-------------+ +--------+------ ------------------------------------+ | 1 | iPad 2 WiFi 16GB | | 1 | iPad2 WiFi 16GB | | 2 | iPhone 4S 16GB | | 2 | iPhone4S 16GB | | 3 | iPod Touch(第 4 代)8GB | | 3 |iPod Touch 第 4 代 8GB | +--------+-------------+ +--------+------ ------------------------------------+

现在我想做的是比较这两个表,如您所见 iPad 2 WiFi 16GBiPad2 WiFi 16GBiPod Touch(4th Gen)8GBiPod Touch 4th Generation 8GB 两者是相同的,但它不显示如果我输入查询 where Table1.model = Table2.model因为它们不是完全匹配的。我想做的是使用like 或任何其他方式将这些行与mysql 查询进行比较,以便比较两个相似的表行。请让我知道如何编写这样的 sql 查询。

我尝试了以下 sql 查询,但它没有返回所有行,就像它没有返回上面示例中提到的那些类型的行一样。

SELECT table1.model as model1, table2.model as model2
FROM table1,table2 WHERE table1.model REGEXP table2.model 

【问题讨论】:

  • 阅读一些关于FULLTEXT Search 的内容也许对你有帮助。
  • 通常这种事情是通过具有“关键词”的第三个表和一个将这些与您的表相匹配的表来完成的。每行一个关键字,然后对此进行连接,并按点击数排名。
  • @JohnWoo 好的,我会看看它.....

标签: php mysql compare


【解决方案1】:

两个问题 - 描述是标准的(描述不会改变)还是由用户输入?如果它们是标准的,则添加一个整数列并在此列上进行比较。

如果它是由用户输入的,您的工作会更复杂,因为您正在寻找更模糊的搜索。我使用二元搜索算法对两个字符串之间的相似度进行排序,但这不能直接在 mySQL 中完成。

您可以使用 LIKE 代替模糊搜索,但如果您最终将“%”放在搜索词的开头,则它的效率仅限于执行表扫描。此外,这意味着您可以在您选择的子字符串部分上获得匹配,这意味着您需要提前知道子字符串。

一旦我知道您要做什么,我很乐意详细说明。

EDIT1:好的,鉴于您的详细说明,您将需要进行模糊样式搜索,正如我所提到的。我使用二元组方法,该方法涉及获取用户输入的每个条目并将其拆分为 2 或 3 个字符的块。然后我将这些块中的每一个存储在另一个表中,每个条目都键入回实际描述。

例子:

描述1:“快速前进” 说明2:“向前冲刺”

如果将每个字符分成 2 个字符块 - 'A'、'f'、'fa'、'as'、'st'......

然后,您可以比较匹配两个字符串的 2 个字符块的数量,并获得一个“分数”,这将意味着两者之间的准确性或相似性。

鉴于我不知道您使用的是哪种开发语言,我将省略实现,但这需要在 mySQL 中不明确地完成。

或者懒惰的选择是使用像亚马逊这样的云搜索服务,它会根据你给它的术语提供搜索……但不确定它们是否允许你不断添加新的描述来考虑,这取决于你的应用程序,它可能有点贵(恕我直言)。

R

有关二元组实现的另一篇 SO 帖子 - 请参阅此 SO bigram / fuzzy search

--- 每个提问者详细说明更新---

首先,我假设您阅读了我提供的链接上的理论。第二,我会尽量保持它与数据库无关,因为它不需要 mySQL(尽管我使用它,而且它效果很好)

好的,所以只有当可能的匹配项相对较小时,bigram 方法才能在创建/比较内存中的数组时正常工作,否则它会受到表扫描性能的影响,例如没有索引的 mysql 表相当快。因此,您将利用数据库的优势来帮助您进行索引。

您需要一张表格来保存用户输入的“术语”或您要比较的文本。最简单的形式是一个有两列的表,一个是唯一的自增整数,它将被索引,我们将在下面调用 hd_id,如果字符串很短,第二个是 varchar(255),如果可以,则为 TEXT变长 - 你可以随意命名。

然后,您需要创建另一个至少包含三列的表 - 一个用于引用列返回到另一个表的自动递增列(我们将在下面将此称为 hd_id),第二个将是 varchar () 最多说 5 个字符(这将保存你的二元组),我们将在下面称之为“二元组”,第三个是下面称为 b_id 的自动递增列。该表将保存每个用户条目的所有二元组,并与整个条目相关联。您需要自己索引 varchar 列(或在复合索引中按顺序排列)。

现在,每次用户输入您要搜索的术语时,您需要在第一个表中输入该术语,然后将其分解为二元组,并使用对整体的引用将每个块输入到第二个表中第一个表中的术语来完成关系。这样,您在 PHP 中进行剖析,但让 mySQL 或任何数据库为您进行索引优化。在二元组阶段存储表 1 中为计算阶段生成的二元组数量可能会有所帮助。下面是一些 PHP 代码,可让您了解如何创建二元组:

// split the string into len-character segments and store seperately in array slots
function get_bigrams($theString,$len)   
{
   $s=strtolower($theString);
   $v=array();
   $slength=strlen($s)-($len-1);     // we stop short of $len-1 so we don't make short chunks as we run out of characters

   for($m=0;$m<$slength;$m++)
   {
      $v[]=substr($s,$m,$len);
   }
   return $v;
}    

不用担心字符串中的空格 - 如果您考虑模糊搜索,它们实际上非常有用。

所以你得到了二元组,将它们输入到表格中,通过索引列链接到表 1 中的整体文本......现在怎么办?

现在,每当您搜索诸如“我最喜欢的要搜索的术语”之类的术语时,您都可以使用 php 函数将其转换为一个二元数组。然后,您可以使用它在二元表 (2) 上创建 SQL 语句的 IN (..) 部分。下面是一个例子:

select count(b_id) as matches,a.hd_id,description, from table2 a
inner join table1 b on (a.hd_id=b.hd_id)
where bigram in (" . $sqlstr . ")
group by hd_id order by matches desc limit X

我已将 $sqlstr 作为 PHP 字符串引用 - 您可以使用 implode 或从 get_bigrams 返回的数组上的任何内容,将它自己构建为一个逗号分隔的列表,从 bigram 函数中得到,或者如果您也喜欢参数化。

如果操作正确,上面的查询会根据您选择的二元组的长度返回最匹配的模糊搜索词。您选择的长度会根据您对整个搜索字符串的预期长度产生相对效果。

最后 - 上面的查询,只是给出了一个模糊的匹配排名。您不仅可以比较匹配项,还可以比较匹配项与整体二元组计数来进行改进和增强,这将有助于消除长搜索字符串与短字符串相比的偏差。我已经停在这里了,因为在这个时刻它变得更加特定于应用程序。

希望这会有所帮助!

R

【讨论】:

  • 模型是由用户输入的,所以我必须匹配并提取它们是否意味着相同。如果它们像 iPod Touch(4th Gen)8GBiPod Touch 4th Generation 8GB 并且它们都包含相同的含义,那么它们是相似的。我必须以这种方式进行比较。
  • 这里是一个简单版本搜索答案的链接,但根据您的阐述,我认为这不会。 stackoverflow.com/questions/3276904/…
  • 我正在使用 PHP,请告诉我 bigram 在 PHP 中的工作方式是否与 similar_text or Levenshtein or metaphones 完全一样??
  • 简而言之,这就是您要找的东西...让我为所有人提供一个编辑起点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多