我需要帮助。
我有一个表,其中只有两个列: ID和NAME,这些数据:
ID | NAME
1 HOME
2 GAME
3 LINK我想显示,例如,行与名称:家庭,如果用户搜索:主页或两层,或埃莫或HMEO,等等.-所有来自word主页的排列。
我无法将所有这些排列和搜索保存到mysql中,因为有些单词太大(9-10个字符),每9个字符的字数超过40 MB。
发布于 2018-11-01 11:31:39
解决此问题的一种方法是将数据库中的每个名称中的排序字符集存储为附加列,然后在搜索之前对用户输入的字符串进行排序,例如,数据库有
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发布于 2018-11-01 13:04:41
这听起来像是一个“请帮我做作业”的问题。很难想象这适用于什么现实世界的问题,也没有标准的解决办法。在这里向你的家庭作业寻求帮助是可以的,但是你应该说是这样的。
每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;
}请注意,这里的散列机制并不唯一地标识单个单词,而是足够具体到索引(在散列上)有效的程度。
相乘而不是添加会产生更少的碰撞,但会有更大的溢出风险(这将造成实现之间的模糊性)。
但是,散列和单个字符(类似)只会减少潜在匹配的数量。要使查询明确地运行,您需要更进一步。您可以向包含字符串长度的表(以及包含哈希的索引)添加一个属性--这将是更有选择性的(即提高索引的有效性),但仍然不确定。
对于确定的方法,您需要在查询中指定数据不包含您要查找的单词中不包含的字符。
这样做的错误方法是添加一个指定“和不喜欢.”的循环。
这样做的一个有效方法是在查询中添加一个测试,该测试将替换表属性中显示在要搜索的单词中的所有字母,这些字符将导致一个零长度字符串。
https://stackoverflow.com/questions/53100298
复制相似问题