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

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

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

6 ответов


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

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

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


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

VARCHAR (X)

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


текст

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


MEDIUMTEXT

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


LONGTEXT

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


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

  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() на основе в размере, а не название типа. Для обновлено обсуждение включения / выключения хранения больших столбцов текста / blob, см. этой .


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

(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 двигатель хранения. Это может быть по-другому в других, например, InnoDB.)