Чем отличается тип varchar от char в MySQL? Читал вроде и тот и тот хранит 0-255 количество символов
FokS
В столбце типа CHAR длина поля постоянна и задается при создании таблицы. Эта длина может принимать любое значение между 1 и 255 (что же касается версии MySQL 3.23, то в ней длина столбца CHAR может быть от 0 до 255). Величины типа CHAR при хранении дополняются справа пробелами до заданной длины. Эти концевые пробелы удаляются при извлечении хранимых величин.
Величины в столбцах VARCHAR представляют собой строки переменной длины. Так же как и для столбцов CHAR, можно задать столбец VARCHAR любой длины между 1 и 255. Однако, в противоположность CHAR, при хранении величин типа VARCHAR используется только то количество символов, которое необходимо, плюс один байт для записи длины. Хранимые величины пробелами не дополняются, наоборот, концевые пробелы при хранении удаляются (описанный процесс удаления пробелов отличается от предусмотренного спецификацией ANSI SQL).
Никита Данилов
лучший ответ Char это массив символов статический. То есть сколько укажешь столько и будет занимать
varchar динамический. Сколько в него запишешь символов столько и будет занимать
- Чем отличается include от require? Чем отличается include от require?
- Что указывается например в VARCHAR (34) количество байт или символов?
- Символьные типы в MySql — CHAR, VARCHAR, TEXT — влияет ли кодировка на выделяемую память?
- Как в поле mysql разрешить более 255 символов, например 2000?
- Как установить AUTO_INCREMENT — 0 в таблице MySQL (MyISAM) если имеется запись с id — 255, тип поля tinyint (3) UNSIGNED
Новые вопросы
- Как упорядочивать номера записей в базе данных mysql?
- Код на PHP + mySQL механизм взаимодействия
- MySQL Error Not connection задолбала
- КАК СОЗДАТЬ СТОЛБЕЦ В MYSQL SAMP
- PHP MySQL выдернуть записи и тут же их удалить вернув результат
Выбор типа данных для строк/текста (char vs varchar vs text)¶
В PostgreSQL есть три типа данных для хранения текстовой информации:
- character(n), char(n) — текст фиксированной длины (строка всегда имеет строго заданный размер)
- character varying(n), varchar(n) — текст с ограничением по длине (максимальная длина строка может быть ограничена)
- text — текст неограниченной длины
Физически максимальный размер любых строк в PostgreSQL ограничен одним гигабайтом (1GB).
Логическое ограничение на максимальный размер строки (char(n), varchar(n), где n — логическое ограничение), задаваемое пользователем для конкретного поля, лимитирует количество символов в строке, а не длину строки в байтах. Поэтому, несмотря на физический лимит на максимальный размер строки в 1GB, реальное максимальное количество символов в строке может быть меньше, так как различные кодировки символов могут использовать больше одного байта для представления одного символа.
CHAR(N)
Этот тип всегда имеет ограничение по длине. Даже, если длина не задана (char), то подразумевается, что она равна единице, то есть char ~ char(1).
Тип имеет одну особенность, которая выделяет есть среди других текстовых типов. Так как поля с этим типом имеют фиксированный размер (не больше / не меньше заданного), то, при сохранении в таблицу у всех строк, длина которых меньше этого размера, оставшееся пустое место в конце строки заполняется пробелами. Поэтому при сохранении значения ‘123’ в поле с типом char(6) в таблицу реально сохранится ‘123___’. Это может стать неприятным сюрпризом.
При операциях сравнения полей с типом char(n) пробелы в конце строки игнорируются.
denis=# SELECT '123 '::char(6) = '123'; ?column? ---------- t (1 row)
VARCHAR
Тип без заданной длины интерпретируется PostgreSQL, как безразмерная строка эквивалентная типу text. При попытке записать в текстовое поле ограниченной длины значение, которое превышает заданные размеры, генерируется ошибка. Строка этого типа хранится в базе данных без изменений (в отличии от char(n)), поэтому нагрузка на процессор при обработке varchar-строк немного меньше, чем при работе с char(n).
TEXT
Этот тип позволяет сохранять строки размером до одного гигабайта. Поэтому его часто используют для хранения текстов, html-страниц и прочей тестовой информации размер которой превышает одну строку текста.
Тип text является специфическим типом PostgreSQL, поэтому при разработке приложений для работы с разными СУБД, лучше использовать безразмерный varchar для лучшей переносимости бизнес-логики.
Резюме¶
Все текстовые поля имеют практически одинаковый формат хранения на диске, поэтому разницы в скорости обработки полей с разными текстовыми типами практически нет. А поля с ограничением по длине обрабатываются даже чуть дольше, чем поля неограниченной длины.
Для хранения строк довольно комфортным выбором будет тип varchar без ограничения по длине (если нет жесткого условия, которое не в коем случае нельзя нарушить). Тип char имеет ряд специфических особенностей, которые в большинстве случаев будут только мешать при работе с базой данных. Тип text является специфическим для PostrgeSQL и не имеет никаких преимуществ/недостатком перед типом varchar без ограничения по длине.
CHAR или VARCHAR? А может быть BLOB?
На диске запись всегда упаковывается. То есть, концевые пробелы не имеют никакого значения с точки зрения дискового пространства.
Количество концевых пробелов учитывается только для varchar. Значение char «добивается» пробелами до объявленной длины только тогда, когда с ним производятся операции присвоения или передача данных на сторону клиента.
Поэтому с точки зрения эффективности хранения различия между char и varchar практически нет. И для работы нужно выбирать то, что удобнее. Как правило это varchar.
Клиентские компоненты могут (или не могут) осуществлять обрезание концевых пробелов для столбцов CHAR. В зависимости от склонностей разработчика такого набора обрезание пробелов может быть по умолчанию, а может и потребовать установки в True какого-либо свойства или на уровне DataSet, или на уровне конкретного поля (TStringField). Поэтому, если вас замучили концевые пробелы в строках, посмотрите на свойства компонент.
Нужно отметить, что ни BDE ни dbExpress не могут выполнять обрезание концевых пробелов у строк.
Поля типа BLOB
Поля этого типа позволяют хранить безразмерную произвольную двоичную информацию (поэтому поля типа BLOB не имеют свойства «набор символов»). Запись на диск производится сегментами. Дисковый сегмент блоба это вовсе не то, что имеется в виду при объявлении столбца BLOB (SEGMENT SIZE xx). Сервер сам разбирается, как хранить конкретное значение blob на диске. Указание размера сегмента при объявлении столбца BLOB не даст никакого выигрыша или проигрыша в производительности. Оно нужно только для приложений, написанных на C (Embedded SQL) при помощи GPRE. Например, в IBX размер буфера для чтения-записи blob определен жестко в 16К, и именно такими «сегментами» оперирует IBX. Поэтому определять размер сегмента при объявлении blob не имеет смысла.
Существуют предопределенные подтипы (SUB_TYPE) BLOB: 0 – двоичные данные, 1 – текстовые данные. На самом деле разницы между ними нет, и подтип имеет значение только для вашего приложения (или при написании фильтров BLOB). Пользовательские подтипы можно определить, указав SUB_TYPE с отрицательным знаком – -1, -2, -10, -200 и т. д., и опять же это имеет значение только для приложения, работающего с данными или для фильтра.
Сегменты BLOB всегда записываются на свободное пространство, и занимают только действительный объем данных BLOB.
Если размер BLOB превышает размер страницы, то создается массив указателей на страницы BLOB. При очень больших размерах BLOB могут появиться указатели на страницы указателей BLOB.
При изменении записи, если содержимое blob не менялось, его blobID остается тем же самым. Собственно, в новой версии записи пишутся только те поля, которые были изменены. Следовательно, при модификации записи, если не затронуто поле BLOB, данные blob не «дублируются». Если же блоб меняется, то как и версия записи, он находится на диске в двух экземплярах – старом и новом. Учитывайте это для блобов, хранящих большой объем данных.
Примечание. Индексировать по полям BLOB невозможно.
CHAR или BLOB?
- Если длина поля < 255 символов, то
- лучше использовать VARCHAR – по хранению varchar на 2 байта больше char, зато в приложениях не надо писать отрезание концевых пробелов у строк.
- в старых версиях IB при использовании VARCHAR могут возникнуть проблемы с производительностью при использовании протокола TCP/IP.
- не имеет смысла использовать BLOB – выборка BLOB осуществляется по его идентификатору, поэтому происходит чуть дольше и требует немного больше затрат на программирование.
- Можно использовать как CHAR или VARCHAR, так и BLOB. Индексирование по полями такой длины невозможно, к тому же есть шанс что однажды записываемые данные превысят 10000 символов, и может быть BLOB подойдет больше. Ориентируйтесь только на удобство работы с такими данными в приложении.
- лучше использовать BLOB. Подтип может быть любой, информацию в таком поле можно хранить произвольную и не беспокоиться о размере данных. Стоимость доступа к данным такого размера полностью компенсирует разницу в способах хранения и извлечения полей типа CHAR и BLOB.
Конвертация данных
В Firebird и Yaffil, в 3-м диалекте появилась возможность при insert (update?) содержимое блоба задавать обычной строкой. В остальных серверах при подобных действиях будет выдано стандартное сообщение о невозможности конвертации данных.
Вместе с тем уже давно существуют UDF перевода блоба в строку и обратно (FreeUDFLib и другие).
Возможные проблемы
Индексирование
- Строковые независимо от типа поля имеют ограничение на длину индекса – 84 байта при указании COLLATE и 252 байта – без COLLATE.
- BLOB-поля не могут быть проиндексированы.
Поиск
- Для поиска по полям типа CHAR, VARCHAR и BLOB можно использовать операторы STARTING WITH (начинается с), LIKE (начинается, содержит, или заканчивается на) и CONTAINING (содержит). В BLOB этими операторами можно искать произвольную информацию (необязательно текстовую), однако необходимо учитывать что поиск в BLOB может осуществляться только перебором записей.
- Если поиск производится по окончанию, например, LIKE ‘%ов’, то такой запрос по полю CHAR выдаст 0 записей, если длина значения поля хотя бы на один символ меньше объявленной длины поля. Это происходит потому, что CHAR при сравнении добивается до длины поля пробелами, и получается, что ‘Иванов ‘ не подходит под условие поиска ‘%ов’. Для решения этой проблемы нужно пользоваться VARCHAR
- Поиск или упорядочивание (ORDER BY) с использованием функции UPPER возможен только для полей типа CHAR или VARCHAR, т. к. только они имеют свойство CHARACTER SET (BLOB содержит только произвольную двоичную информацию, т. е. необязательно текстовую). Кроме того, для UPPER поля CHAR и VARCHAR должны иметь соответствующий COLLATE либо в объявлении типа поля, либо в выражении поиска или сортировки.
Примечание. Вы можете написать собственную функцию, аналогичную UPPER, и избежать указанной проблемы.
Выборка данных
- При конкатенации строковых полей в запросе нужно учитывать, что CHAR-поля будут «расширены» до указанной длины пробелами, а VARCHAR – нет. Например, если в запросе производится «сборка» фамилии, имени и отчества
select last_name||first_name||middle_name from clients
то результат будет приблизительно такой: «Иванов Иван Иванович». А если это будут VARCHAR-поля, то такой же запрос выдаст результат в виде «ИвановИванИванович».
Для решения этой проблемы можно для CHAR использовать UDF (типа RTrim), а для VARCHAR – вставлять дополнительные пробелы (||» «||).
- Для многоязыковых баз данных BLOB не могут быть перекодированы из одной кодировки в другую. Например, если сервер поддерживает кодировки WIN1251 и KOI8R, и база создана в WIN1251, возможно подключиться (через компоненты прямого доступа) указывая lc_ctype=KIO8R в параметрах коннекта. При этом информация будет перекодироваться из win1251 в koi8r и наоборот для всех строковых типов данных, кроме BLOB. Для конвертации данных blob хотя бы при выборке придется написать собственную UDF.
Вставка и модификация данных
- Поля BLOB невозможно передавать как параметр запроса или хранимой процедуры в BDE 2.5x и 3.x (такая возможность появилась только в BDE 4.0 и у компонент Delphi 3.0). Это приводит к необходимости использования TQuery и передачи данных в BLOB-поля через TBlobStream. Сам сервер не имеет проблем с получением или передачей blob в виде параметров запроса или параметров процедур.
Создание переносимой базы данных
- Стандарт ANSI SQL в частности определяет типы полей, но безусловно реализация этих типов, способ хранения и обработки определяет изготовитель конкретного SQL-сервера. Для обеспечения хоть какой-то возможной переносимости следует пользоваться совместимыми типами, игнорируя преимущества использовани типов данных (например CHAR в InterBase). Вам необходимо обратиться к документации или справочным файлам BDE (BDE32.HLP), для того чтобы определить совместимость различных типов между выбранными вами SQL-серверами.
Copyright iBase.ru © 2002-2023
Разница между CHAR, VARCHAR и TEXT
MySQL предоставляет 3 типа данных для хранения текстовой информации: CHAR, VARCHAR и TEXT .
С каким же из них проще всего работать и какой тип данных обеспечивает более быструю работу?
Отличия в скорости работы между этими тремя MySQL типами данных будет очень тяжело выявить, до тех пор пока ваша база данных не разрастётся до довольно больших объёмов.
Данные типа CHAR, которые имеют фиксированную длину, быстрее всего сохраняют и достают информацию но могут потреблять излишнее дисковое пространство.
VARCHAR, строка изменяющейся длины, работает медленнее чем CHAR но не потребляют излишнее дисковое пространство.Тип TEXT переменная типа BLOB – он занимает больше места и I/O чем предыдущие 2 типа.
Использование типа CHAR для текстовых данных технически самый быстродействующий способ, но данные типа CHAR имеют ограничение длинны в 255 символов. Последняя версия СУБД MySQL позволяет хранить в переменной типа VARCHAR данные длиной вплоть до 65,535 символов, это максимальная длинна этого типа данных.
Тип TEXT более привлекательный с первого взляда, потому что в отличии от типа VARCHAR, в нём можно хранить множественные TEXT элементы в одной ячейке. Для того что бы включить полнотекстовое индексирование данных типа text, необходимо что бы тип таблицы был MyISAM так как он не обращает внимания на то какой тип данных
