Xpoint
   [напомнить пароль]

utf8mb4 или utf8 ? Что выбрать лучше?

Метки: [без меток]
2019-02-19 17:50:31 [обр] German[досье]

вот пишут:

https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8.html
The utf8mb3 character set is deprecated and will be removed in a future MySQL release. Please use utf8mb4 instead. Although utf8 is currently an alias for utf8mb3, at that point utf8 will become a reference to utf8mb4. To avoid ambiguity about the meaning of utf8, consider specifying utf8mb4 explicitly for character set references instead of utf8.

То есть при создании таблицы использовать utf8mb4 ? Это же поставить по умолчанию ?

спустя 7 часов [обр] Евгений Седов aka KPbIC(10/187)[досье]
Да.
спустя 14 часов [обр] German[досье]
Спасибо. Я опасался каких-то подводных камней, о который не знаю
спустя 18 часов [обр] German[досье]

неприятности остаются
Вот такой запрос выдают правильную кодировку в utf8

$sql =  qq { 
    SELECT  xitem.types, xdate.paid, xdate.dates, xitem.include, xfirm.brand, xtext.texts, 
    xitem.courtage, xfirm.phone1, xfirm.phone2, xfirm.fax, xfirm.url, xfirm.email, xitem.iditem
    FROM xdate, xtext, xitem, xfirm
    WHERE (xdate.iditem =  xtext.id) 
    AND (xdate.iditem = xitem.iditem)
    AND (xfirm.login = xitem.logfirm)    
    AND (xdate.dates >= date_add(CURRENT_DATE, interval xdate.days DAY))
    ORDER BY IF(xitem.types>39, 40, xitem.types), xdate.dates, xdate.paid DESC
    };

$sth = $dbh->prepare($sql);
$sth->execute();
my $h2 = 0; # печать заголовков
while (@ary = $sth->fetchrow_array() ) {

а несколько запросов другого типа выдают Latin 1 — 1252
Запросы такого типа:

my $sql = qq{SELECT HIGH_PRIORITY SQL_SMALL_RESULT
                    login, password, account, credit, filial, metro,
                    brand, fullname, inn, licence, url,
                    email, code, phone1, phone2, phone3, fax,
                    city, postindex, street, domkorp, office, floor
                    FROM xfirm
                    WHERE   login = "$r_DATA->{'login'}"
                    AND     password ="$r_DATA->{'password'}" LIMIT 1};

my @firm = $dbh->selectrow_array($sql);

При создании всех таблиц указывалось DEFAULT CHARSET=utf8mb4. По умолчанию такая же кодировка. Я надеялся, что уничтожил Latin 1. Но она откуда-то выскакивает.

спустя 2 часа 3 минуты [обр] Евгений Седов aka KPbIC(10/187)[досье]
В каких полях проблемы?
спустя 2 часа 12 минут [обр] German[досье]

В первом запросе - никаких проблем. Причем в первом запросе есть таблица второго запроса — и она правильно возвращает значения.

Проблемы во всех полях с Русской кодировкой во втором запросе: metro, city, street, domkorp. Правда, перечисленных полей в первом запросе нет, так что не факт, что таблица правильно возвращает значения в первом запросе.

спустя 36 минут [обр] German[досье]

Поменял xfirm.brand, присутствующий в первом запросе на Русские буковки. И все равно — из первого запроса вс выводится правильно в utf8

То есть, из таблички xfirm в первом запросе правильно выводит Русский текст — а во втором запросе выводит в кодировке, которая как ни странно еще и меняется. Хотя везде стоит use utf8, все файлы сохранены как utf8 с BOM

спустя 1 час 52 минуты [обр] German[досье]
меняются кодировки там, где я вывожу текст в поля формы — для последующей правки
спустя 1 час 42 минуты [обр] German[досье]

Запрос создания таблицы

my $sql =  qq {
        CREATE TABLE IF NOT EXISTS xfirm(
        login       CHAR(8) NOT NULL PRIMARY KEY DEFAULT "",
        password    CHAR(8) NOT NULL DEFAULT "",
        account     FLOAT (9,3) NOT NULL DEFAULT 0, 
        credit      SMALLINT UNSIGNED NOT NULL DEFAULT 0,
        filial      TINYINT UNSIGNED NOT NULL DEFAULT 0,
        metro       CHAR(100) NOT NULL DEFAULT "",
        brand       CHAR(100) NOT NULL DEFAULT "",
        fullname    CHAR(250) NOT NULL DEFAULT "",
        inn         CHAR(20) NOT NULL DEFAULT "",
        licence     CHAR(250) NOT NULL DEFAULT "",
        url         CHAR(250) NOT NULL DEFAULT "",
        email       CHAR(250) NOT NULL DEFAULT "",
        code        CHAR(20) NOT NULL DEFAULT "495",
        phone1      CHAR(20) NOT NULL DEFAULT "",
        phone2      CHAR(20) NOT NULL DEFAULT "",
        phone3      CHAR(20) NOT NULL DEFAULT "",
        fax         CHAR(20) NOT NULL DEFAULT "",
        city        CHAR(100) NOT NULL DEFAULT "Москва",
        postindex   CHAR(6) NOT NULL DEFAULT "",
        street      CHAR(100) NOT NULL DEFAULT "",
        domkorp     CHAR(100) NOT NULL DEFAULT "",
        office      CHAR(100) NOT NULL DEFAULT "",
        floor       CHAR(100) NOT NULL DEFAULT "",
        stamp       TIMESTAMP)
        ENGINE = MyISAM  DEFAULT CHARSET=utf8mb4
        };

Вроде всё правильно.
SHOW CREATE TABLE показывает тоже самое, только Москва в ДОСе не показывается. Это вроде так и должно быть

спустя 1 час 47 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]

German[досье]

меняются кодировки там, где я вывожу текст в поля формы — для последующей правки

Думаю, проблема с кодировками где-то тут, а не в базе данных.

А вообще, вам бы программиста нанять хорошего. То, что вы показываете, вызывает массу вопросов.

спустя 8 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
Я вы вам порекомендовал ознакомиться с $ perldoc utf8, $ perldoc perluniintro и $ perldoc Encode.
спустя 27 минут [обр] German[досье]
Думаю, проблема с кодировками где-то тут, а не в базе данных.

$dbh->selectrow_array($sql); мне кажется, способ выбора данных виноват
или даже sub print_form { требует повторного указания use utf8
Я вызываю печать из подпрограммы
Попробую несколько вариантов, хотя многое уже попробовал

Прочесть всю документацию перл — тоже хороший совет. Только кто-то может помочь несколько быстрее.

спустя 49 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
М German[досье] Вы уже много лет в профессии, и все находитесь на уровне ниже джуна. Учиться не хотите. Откладываете на форум кучки кода и ждете, что кто-то за вас сделает вашу работу. Это проявление неуважения к другим людям.
спустя 14 минут [обр] German[досье]

Убрал sub print_form Теперь это не в подпрограмме

my @firm = $dbh->selectrow_array($sql);

Вероятно, именно это портит кодировку, странно, конечно. Ну сделаю массив массивов — и распечатаю всю таблицу способом

$sth = $dbh->prepare($sql);
$sth->execute();
while (@ary = $sth->fetchrow_array() ) {

Если кодировка зависит от способа вывода, должны быть выведено правильно. Но тогда вовсе ничего не логично

Евгений ! Я 10 лет был вне профессии (я писал), сейчас вынужден восстанавливать свои навыки не от хорошей жизни.
Любительский уровень, но не совсем сырой. Неуважения я не проявляю, кто знает, кто профессионал, кто постоянно эти занимается — напишет пару сообщений — и всё станет ясно
Я поблагодарю. Где неуважение? Такого нет.

спустя 15 минут [обр] German[досье]
Массив массивов, можно не делать: просто два вложенных цикла для всей таблицы.
Хотя можно попробовать и строку вывести другим способом, разницы-то нет...
спустя 36 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
не от хорошей жизни... кто профессионал, станет ясно

Тут взрослые все дядьки, ни на слезу не пробить, ни "на слабо" не взять.

вывести другим способом, разницы-то нет

Для юникода принт и конкатенация имеют значение. Пока вы не станете читать документацию, лично я вам помогать не буду.

спустя 19 минут [обр] German[досье]

Я не стану писать, если вы меня отчислите за это с форума. Писать больше нельзя?
— Не стану. Но я ко всем участникам форума отношусь с большим уважением. Могу конкретизировать проблему, иначе ее видно только при внимательном и последовательном чтении.
Евгений! Спасибо вам за помощь. Сейчас попробую все варианты, завтра буду с документацией пробовать. Я никого не хочу на слезу пробить: просто разъясняю, что мне не для баловства нужно.
И сегодня документацию смотрел, просто там тонна материала. А решение где-то на поверхности... так представляется.
Я прочел немало документов по вашей рекомендации. И с большой пользой для себя.

Проблема есть, проблема реальная.
Такой способ тоже не работает:

$sth = $dbh->prepare($sql);
$sth->execute();
while (@ary = $sth->fetchrow_array() ) {

Можно предположить, что наличие текстового поля в запросе (тип TEXT) заставляет базу данных делать правильный вывод в utf8.
Без такого поля нужно сделать специальное указание базе данных выводить в utf8.
Пока единственное, что могу предположить...
Принимаюсь за чтение.

спустя 38 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
Я вас никуда не отчисляю и писать не запрещаю. Но я вам уже дал ссылки на документацию, с помощью которой можно решить вашу задачу. То, что вы не хотите разобраться в материале, это уже ваши проблемы.
спустя 9 часов [обр] German[досье]

Много интересного в документации

Note that if you have non-ASCII, non-UTF-8 bytes in your script (for example embedded Latin-1 in your string literals), use utf8 will be unhappy. If you want to have such bytes under use utf8, you can disable this pragma until the end the block (or file, if at top level) by no utf8; .

То есть мне нужно отключить utf8. Как потом добиться вывода в нужной кодировке пока непонятно. То есть правильно вот так.
no utf8; Но работать не будет. Вероятно, нужно еще везде кодировать-декодировать вручную. Тогда применение юникода в перл лучше считать нереализованным адекватно — и переходить на PHP?
Мне представляется, я читал, что юникод теперь работает в перл, как родной. Похоже это не так.
Не следуйте моим указаниям, я просто разбираюсь

спустя 3 часа 24 минуты [обр] Евгений Седов aka KPbIC(10/187)[досье]
Ну, с 'use utf8' вы разобрались, оно вам не нужно, если только у вас в скрипте нет литералов в юникоде.
Читайте следующие ссылки.
спустя 54 минуты [обр] Евгений Седов aka KPbIC(10/187)[досье]
Вы как-то странно прочитали про use utf8. Во втором абзаце Описания: "Do not use this pragma for anything else than telling Perl that your script is written in UTF-8."
Вы можете оставить 'use utf8' даже если у вас текст скрипта в ASCII, но это никак не поможет вам с кодировками, приходящими извне. Читайте perluniintro.
спустя 4 часа 6 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
То есть мне нужно отключить utf8.
Что-то я не понял, а в чем у вас скрипт?
спустя 2 часа 21 минуту [обр] German[досье]
Что-то я не понял, а в чем у вас скрипт?
Я неверно воспринял это указание: «you can disable this pragma until the end the block». Можно отключить, я прочитал как следует отключить.
Скрипт одинаково действует, если его сохранить в юникоде (с помощью RJ TextEd) или анси. Разницы нет.
Читаю документацию. perluniintro и utf8 прочел. И пока не понял, как именно нужно получать данные из базы данных, чтобы они оставались в юникоде. Или из базы данных они поступают не в уникоде.
Переустанавливаю базу данных, потом еще что-то попробую.
спустя 43 минуты [обр] Евгений Седов aka KPbIC(10/187)[досье]
То есть, у вас в скрипте нет переменных или литералов не в ASCII. Тогда, при чем тут цитата "...if you have non-ASCII, non-UTF-8 bytes in your script..." из которой вы ранее делали смелые выводы относительно неадекватности перла?
спустя 46 минут [обр] German[досье]

Почему в некоторых скриптах есть символы, которые желательно воспринимать, как юникод. Например:
при создании таблицы я использую

        city        CHAR(100) NOT NULL DEFAULT "Москва",

Видимо, Москва должна быть юникодом, чтобы правильно быть переданной в базу данных. Хотя требуются и дополнительные меры для того, чтобы все правильно работало, это я понял.
И я так понял документацию, что можно сохранять скрипты в юникоде, и даже использовать прагму use utf8. Это не помогает, но и не мешает. Не так ли?

С неадекватностью перла я был неправ. Я ожидал, что использование юникода, потребует каких-то прагм, которые вскоре вовсе отменят. Зачем нужны другие котировки, если везде сплошной юникод?
Можно предположить, что записи в юникоде в несколько раз больше чем анси, но едва ли можно сэкономить место на размере кода...

Я ждал простого решения. Например, такого: есть юникод, который полностью вытеснил все прочие кодировки. Если нужно что-то перекодировать из устаревших (всех других) кодировок — то используются дополнительные подпрограммы...

Оказалось, что все совсем не так. Разбираюсь теперь постепенно. Еще не всю рекомендованную вами документацию прочел. Спасибо за помощь.

спустя 11 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
Я так и не понял какое отношение цитата про не-ASCII имеет к вашему скрипту.
спустя 1 день 1 час [обр] German[досье]
Я так и не понял какое отношение цитата про не-ASCII имеет к вашему скрипту.

Я ошибся.
Я переустановил несколько раз базу данных, она почти в порядке:

Variable_nameValue
character_set_clientutf8mb4
character_set_connectionutf8mb4
character_set_databaseutf8mb4
character_set_filesystembinary
character_set_resultsutf8mb4
character_set_serverutf8mb4
character_set_systemutf8
collation_connectionutf8mb4_unicode_ci
collation_databaseutf8mb4_unicode_ci
collation_serverutf8mb4_unicode_ci

Одна переменная character_set_system не вполне правильно установлена, но как ее установить, пока не понимаю. Может это и не нужно?
Документацию читаю, интересно. Хотя простая когда-то база данных (мускул) всё больше становится похожа Oracle

Перл документацию тоже читаю, прямо про мои проблемы пока не нашёл
Признателен за помощь и поддержку

спустя 56 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]

Когда я говорю "прочтите" документацию, то имею в виду "прочесть, понять, уметь использовать". А читать документацию как беллетристику, никому не нужно.

Если бы вы разобрались с perluniintro, то мы бы сейчас с вами обсуждали байты, флаги, дисциплины вывода, а не занимались общими рассуждениями о трудностях бытия.

спустя 5 часов [обр] German[досье]

Это я понимаю (то есть понимаю, что нужно освоить информацию, а не просмотреть ее)
Усвоить я умею единственным не быстрым способом: использовать, понять для чего можно применить. Понять, в каком контексте может возникнуть такая задача. Разберусь, вероятно, не быстро.

Трудности бытия описаны здесь только потому, что собственно кодировка utf8mb4 в доке Перл не упоминается (или не сумел найти). Хотя по смыслу понятно, что Перл считает это вариантом utf8
Кроме того интересно понять все ли верно в базе данных, чтобы не сталкиваться с ошибками из базы данных в дальнейшем, не смешивать ошибки из разных источников...
perluniintro.html - даже записал в отдельный файл (чтобы выбросить ненужное, перевести не вполне прозрачное), сегодня сделаю выборку, что следует протестировать и понять. Может сегодня и успею усвоить существенную часть.

спустя 1 час 16 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
Записали в базу "Я" в ютф8. В скрипте прочитали из базы. Смотрим что в переменной - правильные ли байты пришли. Не надо мудрить и тыкать во все, что под руку попалось.
спустя 6 часов [обр] German[досье]

Очень хочу разобраться с perluniintro. Но вопросы детские. Боюсь будут раздражать.

При повторной загрузке было все криво совсем. Вставил совет из сети (там сегодня очень много дурных советов, но есть и хорошие).

use encoding 'utf8';

$dbh = DBI->connect("DBI:mysql:dbname:localhost","user","pass");
$dbh->do("set character set utf8");
$dbh->do("set names utf8");

После вставки этого кода (только в файл для извлечения из базы данных) — все встало на место, все выводится по-русски (буквы яЯ тоже). Полагаю, это не все что нужно, где-то еще потребуются более глубокие знания.
Проверю: мне, помниться, хватало set names utf8 Но еще не проверил.

По-прежнему, хочу разобраться с perluniintro. Вопросы не срочные, иногда не слишком умные. Можно будет спрашивать? Срочные ответы не нужны.

спустя 29 минут [обр] German[досье]

Проверил ; use encoding 'utf8' тоже нужно, как и set names utf8

use encoding 'utf8';

$dbh = DBI->connect("DBI:mysql:dbname:localhost","user","pass");
                   # $dbh->do("set character set utf8"); # эта закомментированная 
                   # строка не нужна, если для базы данных, таблицы 
                   # или столбца НЕ определена другая кодировка – не юникод.
$dbh->do("set names utf8");

Но разберусь, что это всё значит и всегда ли работает

спустя 19 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
$ perldoc encoding | head -n 6
NAME
    encoding - allows you to write your script in non-ASCII and non-UTF-8

WARNING
    This module has been deprecated since perl v5.18. See "DESCRIPTION" and
    "BUGS".
спустя 57 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
utf8mb4 в доке Перл не упоминается
Наверное потому, что это чисто мускульная кодировка, означающая что-то в духе "utf8 max byte 4".
спустя 18 часов [обр] German[досье]
This module has been deprecated since perl v5.18
Значит у меня некрасивое, приблизительное, временное и нестабильное решение проблемы.
Надо разбираться дальше, точнее, не дальше, а снова...
Спасибо
спустя 56 минут [обр] Евгений Седов aka KPbIC(10/187)[досье]
Надо разбираться дальше, точнее, не дальше, а снова...
Точнее не снова, а наконец. Видно же, что вы потратили время не на изучение предмета, а на поиск решения методом тыка.
Powered by POEM™ Engine Copyright © 2002-2005