mysql中的置换搜索

llew8vvj  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(319)

我需要帮助。
我有一个表,其中只有两列:id和name以及以下数据:

ID | NAME
1    HOME
2    GAME
3    LINK

如果用户搜索:home或omeh或emoh或hmeo等,我想显示例如名为home的行来自单词home的所有排列。
我无法将所有这些排列保存到mysql并在本专栏中搜索,因为有些单词会太大(9-10个字符),每9个字符的单词超过40MB。

xtfmy6hx

xtfmy6hx1#

这听起来像是一个“请帮我做作业”的问题。很难想象这适用于什么现实世界的问题,也没有标准的解决方案。在这里要求帮助做作业是可以的,但你应该说明情况就是这样。
每9个字符的字超过40 mb
你的数学有点不靠谱,但实际上存储器的扩展性不好。撇开存储量不谈,就处理工作负载而言,otoh作为一个解决方案确实可以很好地扩展。
您可以简单地强制执行动态查询:

function mkqry($word)
 {
     $qry="SELECT * FROM yourtable WHERE 1 ";
     $last=strlen($word);
     for ($x=0; $x<$last; $x==) {
          $qry.=" AND word LIKE '%" . substr($word, $x, 1) . "%'";
     } 
     return $qry;
 }

然而,这将总是导致一个完整的表扫描(慢),并不会正确处理的情况下,一个字母出现两次在一个字。
解决方案是使用独立于字符出现顺序的索引函数—非加密哈希。一个明显的候选方法是将字符异或在一起,尽管这只会产生一个字符标识符,这不是很有选择性。所以我建议简单地添加字符代码:

function pos_ind_hash($word)
 {
     $sum=0;
     for ($x=0; $x<$last; $x==) {
         $sum+=ord(substr($word, $x));
     }
     return $sum;
 }

 function mkqry($word)
 {
     $qry="SELECT * FROM yourtable WHERE 1 ";
     $last=strlen($word);
     for ($x=0; $x<$last; $x==) {
          $qry.=" AND word LIKE '%" . substr($word, $x, 1) . "%'";
     }
     $qry.=" AND yourtable.hash=" .  pos_ind_hash($word);
     return $qry;
 }

注意,这里的散列机制并不唯一地标识单个单词,而是足够具体地将卷减少到索引(在散列上)有效的程度。
相乘而不是相加将创建更少的冲突,但溢出的风险更大(这将在实现之间创建模糊性)。
但是hash和单字符like只会减少潜在匹配的数量。要使查询具有明确的行为,您需要更进一步。您可以向包含字符串长度的表(以及带有哈希的索引)中添加一个属性-这将更具选择性(即提高索引的有效性),但仍然不是决定性的。
对于确定方法,您需要在查询中指定数据不包含您要查找的单词中没有的字符。
错误的方法是添加一个循环,指定“and not like…”。
一种有效的方法是在查询中添加一个测试,它将替换表属性中的所有字母,这些字母出现在您要搜索的单词中,结果是长度为零的字符串。

carvr3hs

carvr3hs2#

解决此问题的一种方法是将数据库中每个名称中已排序的字符集存储为一个附加列,然后在搜索之前对用户输入的字符串进行排序,例如数据库具有

ID   NAME   CHARS
1    HOME   EHMO
2    GAME   AEGM
3    LINK   IKLN

然后在php中搜索时,您可以执行以下操作:

$search = 'MEHO';                // user input = MEHO
$chars = str_split($search);
sort($chars);
$search = implode('', $chars);   // now contains EHMO
$sql = "SELECT ID, NAME FROM table1 WHERE CHARS = '$search'";
// perform query etc.

输出

ID   NAME
1    HOME

相关问题