За последние 24 часа нас посетили 26489 программистов и 1510 роботов. Сейчас ищут 828 программистов ...

странное поведение varchar в mysql

Тема в разделе "PHP и базы данных", создана пользователем Ganzal, 28 ноя 2014.

  1. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    сервер:
    Код (Text):
    1. 5.5.40-0ubuntu0.14.04.1
    чарсет/колейшн:
    Код (Text):
    1.      character_set_client  :  utf8
    2.  character_set_connection  :  utf8
    3.    character_set_database  :  utf8
    4.  character_set_filesystem  :  binary
    5.     character_set_results  :  utf8
    6.      character_set_server  :  latin1
    7.      character_set_system  :  utf8
    8.        character_sets_dir  :  /usr/share/mysql/charsets/
    9.      collation_connection  :  utf8_general_ci
    10.        collation_database  :  utf8_general_ci
    11.          collation_server  :  latin1_swedish_ci
    декларация таблицы:
    Код (Text):
    1. CREATE TABLE IF NOT EXISTS `u_user_prefs` (
    2.   `user_id` int(10) unsigned NOT NULL,
    3.   `pref_key` varchar(64) NOT NULL,
    4.   `pref_value` varchar(128) NOT NULL
    5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
    шаг1:
    Код (Text):
    1. INSERT INTO `u_user_prefs` (`user_id`,`pref_key`,`pref_value`) VALUES (1, 'test', 'unrated');
    тест1:
    Код (Text):
    1. SELECT * FROM `u_user_prefs` WHERE `user_id` = 1;
    результат1 (третье поле спецом в хексе):
    Код (Text):
    1. 1   test    756e7261746564
    шаг2:
    Код (Text):
    1. INSERT INTO `u_user_prefs` (`user_id`,`pref_key`,`pref_value`) VALUES (SELECT 1, 'test2', `pref_value` FROM `u_user_prefs`);
    ок, есть строка

    тест2. выбираем тем же запросом что и тест1
    ожидаем увидеть:
    Код (Text):
    1. 1   test    756e7261746564
    2. 1   test2   756e7261746564
    имеем фактически:
    Код (Text):
    1. 1   test    756e7261746564
    2. 1   test2   756e726174656400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    если посчитать то строка получается 256 символов хекс то есть 128 символов оригинальных. то есть инсерт-селект не отсек пустоты при работе с варчаром.
    ну допустим ок.

    шаг3:
    Код (Text):
    1. UPDATE `u_user_prefs` SET `pref_value` = `pref_value`
    тронута одна строка. а?
    тест3. по методике теста1, ожидаем фактические результаты теста2, но видим...
    Код (Text):
    1. 1   test    756e7261746564
    2. 1   test2   756e7261746564
    збс, это излечимо. но продолжаем насиловать детку.

    стираем базу, шаг1, тест1, шаг2, тест2. всё на месте. ну слава богу! а то я уж было испугался что это какой-то временный артефакт был...
    шагН:
    Код (Text):
    1. UPDATE `u_user_prefs` SET `pref_value` = CONCAT(`pref_value`, '+');
    две строки, замечательно.
    тестН: ожидаем увидеть строки "unrated+", их и видим, но они не равны. хекс как всегда помогает понять почему:
    Код (Text):
    1. 1   test    756e72617465642b
    2. 1   test2   756e72617465640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b
    и через шаг3 вот такое уже почему-то не лечится.

    это на девелоперском серваке и только на одной конкретной таблице конкретной базы. на других машинах/базах/таблицах воспроизвести не удается поэтому не считаю это багом, но интересно понять первопричину. идеи есть?
     
  2. metadon

    metadon Активный пользователь

    С нами с:
    6 фев 2006
    Сообщения:
    779
    Симпатии:
    0
    Хорошо бы уметь это дело в отладчике посмотреть, там сразу будет видно из-за чего это происходит
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Ganzal, а что же ты не показал способ каким string as hex делаешь? чтобы мы попробовали в точности воспроизвести. может быть как раз в способе и зарыта собака? типа CAST AS BINARY просирает конец строки… м?
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    заметилось на стороне пхп когда перестало одинаковые визуально строки считать равными. у меня на такие случаи сразу срабатывает отладка методом bin2hex.
    манипуляции с данными делались:
    * напрямую в консольке,
    * через мускул воркбенч,
    * через пма
    * и через пхп.

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