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
корпус: учебники, программы, годы файлов журналов, Гарри Поттер и Кубок огня, научные исследования ведения журнала
просто чтобы уточнить наилучшую практику:
сообщения в текстовом формате почти всегда должны храниться как текст (они заканчиваются произвольно длинными)
строковые атрибуты должны храниться как 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.)