VARCHAR(255) CHARACTER SET utf8 255 байт или 255 символов

Я объявил поле в моей таблице INNODB/MySQL как

VARCHAR(255) CHARACTER SET utf8 NOT NULL

однако при вставке мои данные усекаются до 255 байтов, а не символов. Это может привести к тому, что две завершающие кодовые точки выделенного текста будут вырезаны из двух, что приведет к недопустимому символу. Любые идеи, что я могу делать неправильно

РЕДАКТИРОВАТЬ:

Пример сеанса такой

mysql> update channel set comment="ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬x" where id = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 1

mysql> select id, channelName, comment from channel;
+----+-------------+------------------------------------------------------------------------------------------
| id | channelName | comment                                                                                                                                                                                                                                                         |
+----+-------------+-----------------------------------------------------------------------------------------
|  1 | foo         | ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩ�� |
+----+-------------+-----------------------------------------------------------------------------------------
1 row in set (0.00 sec)

через mysql-admin я смотрю на поле комментария и вижу, что это действительно VARCHAR (255) и использует "UTF-8 Unicode"

от команды

show full columns from channel

я получил

+-----------------------------+------------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| Field                       | Type             | Collation       | Null | Key | Default | Extra          | Privileges                      | Comment |
+-----------------------------+------------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| id                          | int(11)          | NULL            | NO   | PRI | NULL    | auto_increment | select,insert,update,references |         |
| channelName                 | varchar(255)     | utf8_general_ci | NO   |     | NULL    |                | select,insert,update,references |         |
| comment                     | varchar(255)     | utf8_general_ci | NO   |     | NULL    |                | select,insert,update,references |         |
+-----------------------------+------------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+

mysql> ПОКАЗАТЬ ПЕРЕМЕННЫЕ, КАК 'character_set%'

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

person bradgonesurfing    schedule 12.08.2010    source источник
comment
Какую версию mySQL вы используете?   -  person Pekka    schedule 12.08.2010


Ответы (2)


Это удар в темноту, но используете ли вы UTF-8 в качестве набора символов для подключения и клиента? Выполните SHOW VARIABLES LIKE 'character_set%' и посмотрите, говорит ли он вам UTF-8 или latin-1.

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

person Hammerite    schedule 12.08.2010
comment
Я обновил вопрос выводом того, что вы просили. Это помогает? - person bradgonesurfing; 12.08.2010
comment
Ваш набор символов подключения и набор символов клиента оба latin1. Попробуйте следующее: введите SET NAMES 'utf8', а затем повторите попытку вставки, которая не сработала. Если это работает, проблема заключается в соединении и наборах символов клиента. - person Hammerite; 12.08.2010
comment
set NAMES 'utf8' действительно решил проблему. Что именно это сделало? - person bradgonesurfing; 12.08.2010
comment
Это означает, что MySQL предполагает, что когда вы общаетесь с ним, ваши строки закодированы в UTF-8, а не в Latin-1. Это означает, что все ваши строки в кодировке UTF-8 доставляются безопасно, а не переинтерпретируются как строки Latin-1. Я думаю, что здесь происходило то, что ваша строка UTF-8 интерпретировалась как последовательность символов - один символ на байт. Следовательно, было сохранено 255 символов (байтов), соответствующих первым 255 байтам строки. - person Hammerite; 12.08.2010
comment
Супер объяснение. Может ли это быть в строке подключения, а не как дополнительная команда SQL? - person bradgonesurfing; 12.08.2010
comment
CharSet=UTF8 Я отвечаю на свой вопрос. - person bradgonesurfing; 12.08.2010
comment
Если у вас есть привилегии SUPER, вы можете изменить наборы символов по умолчанию для новых подключений, введя SET GLOBAL character_set_client = 'utf8'; SET GLOBAL character_set_results = 'utf8'; SET GLOBAL character_set_connection = 'utf8'; - person Hammerite; 12.08.2010

Согласно руководству, все должно быть в порядке. :

MySQL интерпретирует спецификации длины в определениях символьных столбцов в символьных единицах. (До MySQL 4.1 длины столбцов интерпретировались в байтах.) Это относится к типам CHAR, VARCHAR и TEXT.

Вы случайно не используете версию mySQL до 4.1?

person Pekka    schedule 12.08.2010
comment
О, интересно. Один из нас ошибается. Я был бы поражен, узнав, что MySQL использует здесь символы. Глядя на это. - person scy; 12.08.2010
comment
@Scytale ваше объяснение действительно имеет больше смысла, и я бы тоже предположил, что оно использует байты. Изменение символов может быть связано с тем, что поля VARCHAR() могут превышать 255 байт, начиная с версии 4.1. - person Pekka; 12.08.2010
comment
Ух ты. Прости, что я тебе не поверил. Действительно, это символы для MySQL ≥ 4.1. Я удалю свой неправильный ответ. (Для справки: расчет памяти для достижения ограничения символов выглядит следующим образом: M × w байт, 0 ‹= M ‹= 255, где w — количество байтов, необходимое для символа максимальной длины в наборе символов.) - person scy; 12.08.2010
comment
странно, потому что мои строки UTF-8, кажется, усекаются до 255 байтов, а не символов. Использование MySQL 5.1 в Ubuntu, стандартная установка из apt. - person bradgonesurfing; 12.08.2010
comment
@Брэд, это странно. Вы уверены, что они не обрезаются из-за неправильного ввода символов (например, символы ISO-8859-1, вводимые в поле UTF-8)? - person Pekka; 12.08.2010
comment
См. сделанное выше редактирование образца обновления UTF-8 в таблице. - person bradgonesurfing; 12.08.2010
comment
@Scytale: для UTF-8 w = 4, поэтому VARCHAR(255) потребляет 1020 байт? - person Philipp; 12.08.2010
comment
Я сделал еще одно редактирование, показывающее вывод из отображения полных столбцов из канала, и это необходимо VARCHAR (255) UTF8. - person bradgonesurfing; 12.08.2010
comment
Я даже поместил полный текст обновления SQL в файл и запустил файл -i /tmp/foo.sql, и он сказал мне, что файл был utf-8 - person bradgonesurfing; 12.08.2010
comment
@Брэд действительно странно. Будет ли он вести себя по-другому, если вы измените тип на TEXT? - person Pekka; 12.08.2010
comment
Hammerite обнаружил, что проблема в том, что мое соединение было закодировано в формате latin1. Но спасибо всем присутствующим за участие. - person bradgonesurfing; 12.08.2010