MySQL: большой VARCHAR против текста?


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

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

6 771

6 ответов:

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

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

обновление ли VARCHAR или TEXT хранится inline, или off-record зависит от размера данных, размера столбцов, row_format и версии MySQL. Это делает не зависит от" текст "против " varchar".

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

VARCHAR (X)

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


текст

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


MEDIUMTEXT

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


LONGTEXT

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

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

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

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

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

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

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

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

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

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

ответ:

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

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

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

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

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

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

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

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

(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 vs VARCHAR в "стандарт"(?) MyISAM storage engine. Он может отличаться в других, например, InnoDB.)