Mysql Кодировка mysql

grey109

Новичок
Добрый день.

У меня вопрос наверно больше теоретический.

И так, есть mysql сервер, у которого по умолчанию настроена utf8 кодировка. Есть несколько таблиц, у которых все поля могут содержат только буквы английского алфавита и цифры, потому для них (и на саму таблицу и на поля) установлена кодировка latin1_general_ci. Есть смешанные таблицы с кодировкой utf8_general_ci, у которых часть полей с кодировкой latin1_general_ci, а часть utf8_general_ci.

Подскажите, сильно ли влияет и влияет ли вообще на производительность когда mysql сервер в одной кодировке, а таблицы/столбцы в другой? Наверно ведь происходят какая-то внутренняя конвертация данных при запросах/ответах когда база в одной кодировке, а после в другой? Если это всё глупости?

Как правильно поступить, когда нужно хранить данные и в utf8 и в latin1? Имеет смысл так извращаться или хранить всё в uft8 и не заморачиваться?

Спасибо.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Как правильно поступить, когда нужно хранить данные и в utf8 и в latin1? Имеет смысл так извращаться или хранить всё в uft8 и не заморачиваться?

Спасибо.
utf8 включает в себя весь latin1 целиком, поэтому смысла разделять особо нет.
В mysql у колонок нет своей отдельной кодировки, это collation, и его нельзя выбрать неподходящим кодировке таблицы. Поддерживаемые collations для кодировок можно посмотреть запросом show collations.

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

Collation влияет на: поиск по текстовому столбцу, на сравнение между текстовыми столбцами, на порядок сортировки по текстовому столбцу. Очень теоретически можно словить какой-то трудноуловимый баг, где скажем, в сравнении может сравнится какая-нибудь буква из latin1 с умляутом из utf8, но это прям, оч редкое.

Ну и к сожалению, в мускуле кодировка, называющаяся utf8 - не является utf8, а полноценный utf8 называется utf8mb4. Historical reasons.
 

WMix

герр M:)ller
Партнер клуба
где скажем, в сравнении может сравнится какая-нибудь буква из latin1 с умляутом из utf8, но это прям, оч редкое.
на счет редко, это ты загнул :) все относительно, мне порою utf8_bin ставить приходится чтоб "ü" и "ue" различало
 

флоппик

promotor fidei
Команда форума
Партнер клуба
на счет редко, это ты загнул :) все относительно, мне порою utf8_bin ставить приходится чтоб "ü" и "ue" различало
Я скорее к тому, что сравнивать столбцы с разным collation логически довольно редко приходится. Понятно, что для поиска по колонке нужно просто выбирать подходящий collation.
 

Фанат

oncle terrible
Команда форума
у "mysql сервер" нет никакой кодировки. Это просто конфигурационная опция, кодировка, которая используется при создании базы, если ты ее не указал явно.
то есть кодировка сервера вообще ни на что не влияет

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

AnrDaemon

Продвинутый новичок
В MySQL utf8 хранится как 3 байта на символ (всегда), utf8mb4 хранится как 4 байта на символ (тоже всегда).
Делать колонку latin1_general_ci есть смысл только в одном случае - если в ней хранятся UUID (IMHO).
На индексе разницы не будет - в индексе хранятся только ID и порядок строк. Разница будет в объёмах хранения. И тут всё зависит от размеров таблиц. Если у вас миллион записей, разница будет в 1:4 мегабайт на колонку. Если миллиард - тут уже разница составит гигабайты.
 

Фанат

oncle terrible
Команда форума
В MySQL utf8 хранится как 3 байта на символ (всегда)
вообще я всегда думал что всегда все байты заняты в кодировке utf-16.
а utf-8 использует столько, склько занимает символ - то есть от 1 до 4
и вроде бы тесты это подтверждают
На индексе разницы не будет - в индексе хранятся только ID и порядок строк.
вот это я нипонил
а как искать-то? Я ж не про праймари индекс говорю, а про индекс по этому полю
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Видимо, в 8.0 это поменяли. Раньше хранилось именно так, для ускорения сортировки.
 
Сверху