Unicode в MySQL Regex?

У меня есть следующая задача: Создайте личный словарь для китайских персонажей. Пользователи выбирают одиночных китайских символов из списка. Затем программное обеспечение просматривает список комбинаций символов и фильтрует все, содержащие символы, которые не входят в список пользователей из отдельных символов. Поэтому, если пользователь изучил 1 (一) и 10 (十), тогда следует показать 11 (十一), но не 12 (十二).

Следующая проблема заключается в том, что имеется около 12 тыс. Одиночных символов и 100 тыс. Комбинаций. Весь список может стать очень длинным. В настоящее время я столкнулся со следующей проблемой: MySQL, похоже, не может выполнять правильное соответствие REGEX с символами Unicode. Однако PHP может быть. Когда я выполняю запрос MySQL (см. Ниже), я получаю много ложных срабатываний. Мне нужно снова фильтровать результаты с PHP. Все это занимает много времени. Теперь у меня есть список из 180 одиночных символов, которые сопоставляются в регулярном выражении SQL, как показано ниже. Результат SQL составляет более 30 000 комбинаций. Для этого SQL-вызов занимает около 6 секунд на компьютере, на котором я запущен. Когда я проверю результаты с PHP, результат будет всего 1182 комбинаций. Это много ложных срабатываний. Кроме того, проверка результатов занимает еще пару секунд. С каждым отдельным символом, который я добавляю в список, время увеличивается примерно на полсекунды. В срочном порядке необходим более эффективный метод.

Чтобы решить эту проблему, мне сначала нужно выяснить, почему MySQL имеет так много ложных срабатываний:

Если я выполняю регулярные выражения с помощью PHP, я использую /regex/u чтобы указать, что объект является юникодом, и это дает мне правильные результаты.

Однако в MySQL я не знаю, как установить такой флаг. Все результаты REGEXP 'regex' возвращаются таким же образом, как если бы я использовал PHP preg_match('/regex/', $subject) вместо /regex/u .

Я попытался изменить сортировку результата на различные utf8_ *, но это не изменило бы результат. Кроме того, добавление полнотекстового индекса по базе данных ничего не делало.

Вот тестовая функция, которую я написал, чтобы выделить проблему. если у вас есть какие-либо другие идеи для проверок, чтобы построить там, чтобы развернуть проблему, пожалуйста, скажите мне.

 $db = mysql_connect('localhost', 'kanji', '************'); $link = mysql_select_db('kanji_data', $db); mysql_query('SET character_set_results=utf8'); mysql_query('SET names=utf8'); mysql_query('SET character_set_client=utf8'); mysql_query('SET character_set_connection=utf8'); mysql_query('SET character_set_results=utf8'); mysql_query('SET collation_connection=utf8_general_ci'); mysql_set_charset('utf8'); echo '<pre>debug: encoding=' .mysql_client_encoding(). '</pre>'; $string = '三|二|四|一|五'; $sql = "SELECT simplified, length(simplified), searchindex FROM chinese WHERE strlen>0 AND simplified REGEXP '($string)+';"; $sql_encoding = mb_detect_encoding($sql); echo '<pre>debug: sql string encoding: ' . $sql_encoding . '</pre>'; echo '<pre>debug: sql string: ' . $sql . '</pre>'; // echo $sql; $rst = mysql_query($sql); echo mysql_errno($db) . ": " . mysql_error($db). "\n"; while ($row = mysql_fetch_array($rst, MYSQL_NUM)) { $len = mb_strlen($row[0]); $result_encoding = mb_detect_encoding($row[0]); $pattern = "/^(三|二|四|一|五)+$/u"; preg_match($pattern, $row[0], $matches); if (count($matches) == 0) { echo "ERROR: "; } echo 'string: '. $row[0] . ' ('.$row[1] .' long mysql, '.$len.' long php, encoding: '.$result_encoding.')'.$row[2] ."<br>\n\n\n"; } 

Результат этой функции можно увидеть на этом веб-сайте .

Если я делаю что-то совершенно неправильное для достижения требуемого результата, я также с удовольствием решаю это по-другому.

Проблема в том, что MySQL не может нормально выполнять REGEX в сочетании с символами Unicode. REGEX всегда работает на основе байта, и Unicode необходимо сгруппировать несколько байтов. Нет решения, только обходные пути.

Один способ обхода, который я сделал, – это индексирование каждого появления букв с другой таблицей, а затем выполнение проверок индекса вместо исходного японского текста.

Является ли набор соединений также установленным на utf8?
В противном случае, если кодировка соединения, например, latin1, сервер mysql интерпретирует (кодированный utf-8) оператор, например

 SELECT x FROM foo WHERE name REGEXP 'Ä.*' 

в виде

 SELECT x FROM foo WHERE name REGEXP 'Ä.*'