Альтернатива функции PHP в MySQL

#php #mysql #transliteration

#php #mysql — сервер #транслитерация #mysql

Вопрос:

Допустим, у нас есть около 1000 строк, которые должны быть транслитерированы в базе данных MySQL. У меня есть следующая функция транслитерации PHP, которая работает хорошо

    public static function tlit($str)
{
    $orig = array("ə", "ü", "i", "ö", "ı", "ç", 'ş', "ğ", "Ə", "Ü", "İ", "Ö", "I", "Ç", 'Ş', "Ğ");

    $tlit = array("e", "u", "i", "o", "i", "c", 's', "g", "E", "U", "I", "O", "I", "C", 'S', "G");

    return $textcyr = str_replace($orig, $tlit, $str);
}
  

Для письма ə у нас есть 2 альтернативы: a и e . например, если word является Əli , я хочу получить оба Eli и Ali внутренних результата.

Для письма ş у нас есть 2 альтернативы: sh и s . например, если word является Şəhər , результат будет выглядеть так:

  • Seher
  • Шехер
  • Сахар
  • Шахар

Для письма ç у нас есть 2 альтернативы: ch и c .

Я не могу понять, как создать альтернативную функцию MySQL, которая будет транслитерироваться следующим образом. Есть какие-нибудь решения?

Комментарии:

1. @Naruto Я хочу переключить эту функцию на MySQL 🙂

2. Не чини то, что не сломано.

3. @heron это означает, что не исправляйте то, что не сломано — просто используйте PHP-скрипт, который у вас уже есть… В конце концов, мы говорим о 1000 записях, импорт которых с помощью php-скрипта займет не более 30 секунд.

4. Как вы собираетесь использовать такую функцию? Вы просто хотите, чтобы MySQL выдавал возможные переходы для одной заданной входной строки, или вы хотите также иметь возможность использовать ее в поиске (что-то вроде SELECT * FROM t WHERE translit(mycol, 'Şəhər'); ) P.S: определение

Ответ №1:

Хорошо, я не эксперт, но как человек, говорящий по-испански, я сталкивался с некоторыми подобными проблемами в прошлом.

Как вы думаете, вы можете решить проблему с сопоставлениями MySQL? Возможно, вы можете выбрать параметры сортировки отсюдаhttp://dev.mysql.com/doc/refman/5.5/en/charset-charsets.html и тогда MySQL сделает транслит за вас.

Возможно, это не решение, но оно может дать некоторые идеи о том, как вы можете искать свою цель.

Ответ №2:

Правильным подходом было бы — использовать приложение, поскольку хранимый MySQL код в таких случаях очень ограничен. Прежде всего — MySQL не имеет никакой (разумной) замены для массивов. Таким образом, вы не можете указать что-либо вроде «списка символов». Далее, замена в СУБД может вызвать множество различных проблем, связанных с параметрами сортировки. И это может быть действительно болезненно — выяснить, что пошло не так в этом случае.

Однако, если ваши списки символов всегда имеют проекцию 1: 1 (таким образом, один символ всегда будет заменен одним символом), тогда вы можете «эмулировать» массивы с помощью простой строки. То есть — поддерживайте связь между вашими заменами через строковый индекс (таким образом, смещение). Используя этот принцип, вы можете написать что-то вроде:

 DELIMITER //
CREATE FUNCTION TRANSLIT_SYMBOLS(str VARCHAR(255), c_in VARCHAR(255), c_out VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
   DECLARE pos    INT DEFAULT 1;
   DECLARE sym    INT DEFAULT 0;
   DECLARE final  VARCHAR(255) DEFAULT '';
   DECLARE till   INT DEFAULT 0;
   IF CHAR_LENGTH(c_in)!=CHAR_LENGTH(c_out) || !CHAR_LENGTH(c_in) THEN
      SIGNAL SQLSTATE '80800' SET MESSAGE_TEXT = 'Incompatible or empty transliteration lists';
   END IF;
   SET till = CHAR_LENGTH(str);
   WHILE pos<=till DO
      SET sym = LOCATE(SUBSTR(str, pos, 1), c_in);
      IF sym THEN
         SET final = CONCAT(final, SUBSTR(c_out, sym, 1));
      ELSE
         SET final = CONCAT(final, SUBSTR(str, pos, 1));
      END IF;
      SET pos = pos 1;    
   END WHILE;
   RETURN final;
END//
DELIMITER ;
  

Здесь:

  • str является входной строкой — поэтому внутри нее будет выполнена замена
  • c_in это строка, символы которой будут рассматриваться как символы для замены
  • c_out это строка, символы которой будут рассматриваться как символы замены.

Таким образом, использование было бы

 mysql> select translit_symbols('foo', 'of', 'ab');
 ------------------------------------- 
| translit_symbols('foo', 'of', 'ab') |
 ------------------------------------- 
| baa                                 |
 ------------------------------------- 
1 row in set (0.00 sec)
  

О сопоставлениях — поскольку эта функция использует прямое смещение строки, она должна корректно работать с многобайтовыми символами, но только если соответствующие соединение и сопоставление данных совпадают. Я не тестировал ее в других случаях, поэтому это может привести к неожиданному результату, если параметры сортировки отличаются — но это опять же, потому что хранимая функция MySQL — плохой выбор для этого случая.