MySQL varbinary против varchar

Мы используем varchar(255) для хранения «ключевых слов» в mysql. Мы столкнулись с проблемой, что mysql игнорирует все конечные пробелы для целей сравнения в "=". Он учитывает конечные пробелы при сравнении «как», но не позволяет нам хранить одно и то же слово с конечными пробелами и без них в столбце varchar, если над ним есть индекс «UNIQUE».

Итак, мы рассматриваем возможность перехода на varbinary. Может ли кто-нибудь предположить, какие могут быть последствия, когда в значениях столбца есть многобайтовые символы?


person ashweta    schedule 10.06.2009    source источник


Ответы (3)


Андомар,

Мы используем версию 5.0.5. Все версии mysql игнорируют конечные пробелы для сравнения. Из руководства:

Все сопоставления MySQL имеют тип PADSPACE. Это означает, что все значения CHAR и VARCHAR в MySQL сравниваются без учета пробелов в конце. Это верно для всех версий MySQL, и не имеет значения, обрезает ли ваша версия конечные пробелы из значений VARCHAR перед их сохранением.

Кроме того, mysql считает, что тексты с/без пробелов в конце дублируются в индексах:

В тех случаях, когда конечные символы дополнения удаляются или сравнения игнорируют их, если столбец имеет индекс, требующий уникальных значений, вставка в столбец значений, отличающихся только количеством завершающих символов, приведет к ошибке дублирования ключа. Например, если таблица содержит «а», попытка сохранить «а» вызовет ошибку двойного ключа.

И нам абсолютно необходим индекс ключевых слов. Итак, я думаю, у нас есть два варианта: varbinary или text. Мы оценим производительность «текста» и многобайтовой функциональности для varbinary.

person ashweta    schedule 17.06.2009

Вот что говорится в руководстве по MySQL о конечных пробелах:

Обработка завершающих пробелов зависит от версии. Начиная с MySQL 5.0.3, конечные пробелы сохраняются при сохранении и извлечении значений в соответствии со стандартным SQL. До MySQL 5.0.3 конечные пробелы удалялись из значений, когда они сохранялись в столбце VARCHAR; это означает, что пробелы также отсутствуют в извлеченных значениях.

Поскольку в вашем вопросе говорится, что MySQL не поддерживает конечные пробелы, я предполагаю, что ваша версия ниже 5.0.3. Рассмотрите возможность использования типа TEXT для вашего столбца; они сохраняют конечные пробелы. TEXT выполнит для вас кодирование и декодирование строки, поэтому вам не нужно беспокоиться о многобайтовых символах.

TEXT работает медленнее, чем VARBINARY. Если фактические данные показывают, что производительность неприемлема, вам, возможно, придется выбрать VARBINARY (или BLOB). В этом случае вы сами должны хранить строку в определенной кодировке, например UTF-8. Пока все ваши клиенты используют одну и ту же кодировку, это будет нормально работать для многобайтовых символов. Протестируйте своих клиентов с различными региональными настройками :)

person Andomar    schedule 10.06.2009
comment
Этот ответ несколько вводит в заблуждение, поскольку он полностью упускает из виду последствия для индексов UNIQUE. См. собственный ответ ашветы для получения дополнительной информации. - person Klaas van Schelven; 27.02.2014

В дополнение к проблеме завершающего пробела ваш UNIQUE INDEX в MySQL будет ограничен 767 байтами (что делает 767/3 ~= 255 для 3-байтового UTF8). Смотрите также:

person Garen    schedule 11.05.2011