我在mySQL中维护一个音乐数据库,如何返回存储在例如mySQL中的结果当人们搜索'Tiesto'时,'Tiësto'?
所有数据都存储在全文索引中,如果这有任何区别的话。
我已经在PHP中使用Levenshtein和在SQL中使用REGEXP - 而不是试图解决这个问题,而只是为了增加可搜索性。
PHP:
function Levenshtein($word) {
$words = array();
for ($i = 0; $i < strlen($word); $i++) {
$words[] = substr($word, 0, $i) . '_' . substr($word, $i);
$words[] = substr($word, 0, $i) . substr($word, $i + 1);
$words[] = substr($word, 0, $i) . '_' . substr($word, $i + 1);
}
$words[] = $word . '_';
return $words;
}
$fuzzyartist = Levenshtein($_POST['searchartist']);
$searchimplode = "'".implode("', '", $fuzzyartist)."'";
MySQL的:
SELECT *
FROM new_track_database
WHERE artist REGEXP concat_ws('|', $searchimplode);
要添加,我经常在PHP中执行字符集转换和字符串卫生,但这些一直是其他方式 - 标准化非拉丁字符。我无法理解执行oppsite流程,但仅在某些情况下才会根据我存储的数据。
答案 0 :(得分:1)
一种可能的解决方案是在“艺术家”旁边的数据库中创建另一列,例如“artist_normalized”。在这里,在填充表时,您可以插入字符串的“规范化”版本。然后可以对artist_normalized列执行搜索。
测试代码:
<?php
$transliterator = Transliterator::createFromRules(':: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD);
$test = ['abcd', 'èe', '€', 'àòùìéëü', 'àòùìéëü', 'tiësto'];
foreach($test as $e) {
$normalized = $transliterator->transliterate($e);
echo $e. ' --> '.$normalized."\n";
}
?>
结果:
abcd --> abcd
èe --> ee
€ --> €
àòùìéëü --> aouieeu
àòùìéëü --> aouieeu
tiësto --> tiesto
魔术是由Transliterator类完成的。指定的规则执行三个操作:分解字符串,删除变音符号,然后重新组合字符串,规范化。 PHP中的Transliterator是建立在ICU之上的,所以这样做依赖于ICU库的表格,这些表格完整可靠。
注意:此解决方案需要PHP 5.4或更高版本,并带有 intl 扩展名。