MySQL: большой VARCHAR против текста? - PullRequest
810 голосов
/ 07 января 2010

У меня есть таблица сообщений в MySQL, которая записывает сообщения между пользователями. Помимо типичных идентификаторов и типов сообщений (все целочисленные типы) мне нужно сохранить фактический текст сообщения как VARCHAR или TEXT. Я устанавливаю входной предел в 3000 символов, что означает, что сообщения никогда не будут вставляться в БД, если они длиннее этого.

Есть ли смысл использовать VARCHAR (3000) или TEXT? В написании VARCHAR (3000) есть что-то нелогичное. Я просматривал другие подобные сообщения о переполнении стека, но было бы неплохо получить представления, относящиеся к этому типу общего хранения сообщений.

Ответы [ 8 ]

789 голосов
/ 07 января 2010
  • TEXT и BLOB хранятся вне таблицы, а таблица просто имеет указатель на местоположение фактического хранилища.

  • VARCHAR хранится в соответствии с таблицей. VARCHAR быстрее при разумном размере, компромисс которого будет быстрее, зависит от ваших данных и вашего оборудования, вы хотите сравнить сценарий реального мира с вашими данными.

Обновление Будет ли VARCHAR или TEXT храниться встроенным или вне записи, зависит от размера данных, размера столбцов, формата строки и версии MySQL. не зависит от "text" и "varchar".

447 голосов
/ 01 ноября 2012

Можете ли вы предсказать, как долго будет вводить пользователь?

VARCHAR (X)

Дело: имя пользователя, адрес электронной почты, страна, тема, пароль


TEXT

Дело: сообщения, электронные письма, комментарии, форматированный текст, HTML, код, изображения, ссылки


MEDIUMTEXT

Дело: большие тела json, короткие и средние книги, строки csv


LONGTEXT

Кейс: учебники, программы, годы журналов, Гарри Поттер и кубок огня, ведение научных исследований

215 голосов
/ 08 января 2010

Просто чтобы уточнить лучшие практики:

  1. Текстовые сообщения почти всегда должны храниться в формате TEXT (они заканчиваются произвольно длинными)

  2. Строковые атрибуты должны храниться как VARCHAR (имя пользователя, тема и т. Д.).

Я понимаю, что у вас есть лимит внешнего интерфейса, который хорош, пока его нет. * ухмылка * Хитрость заключается в том, чтобы рассматривать БД отдельно от приложений, которые к ней подключаются. То, что одно приложение накладывает ограничение на данные, не означает, что данные изначально ограничены.

Что в самих сообщениях заставляет их никогда не превышать 3000 символов? Если это просто произвольное ограничение приложения (скажем, для текстового поля или чего-то еще), используйте поле TEXT на уровне данных.

32 голосов
/ 07 января 2010

Отказ от ответственности: я не эксперт по MySQL ... но это мое понимание проблем.

Я думаю, что TEXT хранится вне строки mysql, а я думаю, что VARCHAR хранится как часть строки. Для строк mysql есть максимальная длина строки, поэтому вы можете ограничить объем других данных, которые можно хранить в строке, используя VARCHAR.

Также из-за VARCHAR, формирующего часть строки, я подозреваю, что запросы, просматривающие это поле, будут немного быстрее, чем запросы, использующие блок TEXT.

21 голосов
/ 25 июня 2018

Краткий ответ: Нет практических, производительности или хранения, разница.

Длинный ответ:

По сути, нет никакой разницы (в MySQL) между VARCHAR(3000) (или любым другим большим пределом) и TEXT. Первый будет усечен до 3000 символов ; последний будет усечен на 65535 байт . (Я делаю различие между байтами и символами , потому что символ может занимать несколько байтов.)

Для меньших ограничений в VARCHAR есть некоторые преимущества перед TEXT.

  • «меньше» означает 191, 255, 512, 767 или 3072 и т. Д., В зависимости от версии, контекста и CHARACTER SET.
  • INDEXes ограничены тем, насколько большой столбец может быть проиндексирован. (767 или 3072 байт ; это зависит от версии и настроек)
  • Промежуточные таблицы, созданные комплексом SELECTs, обрабатываются двумя различными способами - MEMORY (быстрее) или MyISAM (медленнее). Когда задействованы «большие» столбцы, автоматически выбирается более медленная техника. (Значительные изменения будут внесены в версию 8.0; поэтому этот элемент маркера может быть изменен.)
  • Относительно предыдущего элемента все типы данных TEXT (в отличие от VARCHAR) переходят прямо к MyISAM. То есть TINYTEXT автоматически хуже для сгенерированных временных таблиц, чем эквивалент VARCHAR. (Но это ведет дискуссию в третьем направлении!)
  • VARBINARY похоже на VARCHAR; BLOB похоже на TEXT.

Опровержение других ответов

Оригинальный вопрос задал одну вещь (какой тип данных использовать); принятый ответ отвечал на что-то другое (внеплановое хранение). Этот ответ устарел.

Когда этот поток был запущен и ответили, в InnoDB было только два «формата строки». Вскоре после этого были введены еще два формата (DYNAMIC и COMPRESSES).

Место хранения для TEXT и VARCHAR() основано на размере , а не на имени типа данных . Для обновленного обсуждения о включении / выключении хранения больших столбцов текста / больших двоичных объектов см. this .

5 голосов
/ 01 июля 2018

Предыдущие ответы недостаточно настаивают на главной проблеме: даже в очень простых запросах, таких как

(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) 

может потребоваться временная таблица, и, если задействовано поле VARCHAR, она преобразуется в поле CHAR во временной таблице. Поэтому, если в вашей таблице указано 500 000 строк с полем VARCHAR(65000), только в этом столбце будет использоваться 6,5 * 5 * 10 ^ 9 байт. Такие временные таблицы не могут быть обработаны в памяти и записаны на диск. Можно ожидать, что воздействие будет катастрофическим.

Источник (с метриками): https://nicj.net/mysql-text-vs-varchar-performance/ (Это относится к обработке TEXT против VARCHAR в «стандартном» (?) Механизме хранения MyISAM. Он может отличаться в других, например, InnoDB.)

1 голос
/ 17 апреля 2019

Varchar для небольших данных, таких как адреса электронной почты, в то время как Text для гораздо больших данных, таких как новостные статьи, Blob для двоичных данных, таких как изображения.

Производительность Varchar более высокая, поскольку он полностью запускается из памяти, но это не будет иметь место, если данные слишком велики, например, varchar(4000).

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

Blob намного медленнее, поэтому используйте его, только если у вас мало данных, таких как 10000 изображений, которые будут стоить 10000 записей.

Следуйте этим советам для максимальной скорости и производительности:

  1. Используйте varchar для имен, названий, электронных писем

  2. Использовать текст для больших данных

  3. Отдельный текст в разных таблицах

  4. Использовать запросы левого соединения для идентификатора, такого как номер телефона

  5. Если вы собираетесь использовать Blob, примените те же советы, что и в тексте

Это сделает запросы стоимостью миллисекунды для таблиц с данными> 10 М и гарантированным размером до 10 ГБ.

0 голосов
/ 23 июня 2019

Разница между VARCHAR и TEXT ОГРОМНАЯ . Хотя поля VARCHAR могут быть проиндексированы, поля TEXT - нет. Поля типа VARCHAR хранятся в строке, в то время как TEXT хранятся в автономном режиме, в записях фактически хранятся только указатели на данные TEXT.

Если вам нужно проиндексировать свое поле для более быстрого поиска, обновления или удаления, чем перейти к VARCHAR, независимо от его размера. VARCHAR (10000000) никогда не будет таким же, как поле TEXT, потому что эти два типа данных различны по своей природе.

  • Если вы используете свое поле только для архивирования
  • вам нет дела до данных восстановление скорости
  • вы заботитесь о скорости, но вы будете использовать оператора "% LIKE%" в вашем поисковом запросе, поэтому индексация не сильно поможет
  • Вы не может предсказать ограничение длины данных

чем перейти к тексту.

...