MySQL: большой VARCHAR или TEXT?
У меня есть таблица сообщений в MySQL, которая записывает сообщения между пользователями. Помимо типичных идентификаторов и типов сообщений (все целые типы), мне нужно сохранить фактический текст сообщения как VARCHAR или TEXT. Я устанавливаю front-end limit из 3000 символов, что означает, что сообщения никогда не будут вставляться в db дольше, чем это.
Есть ли обоснование для перехода с VARCHAR (3000) или TEXT? Там что-то о том, как просто писать VARCHAR (3000), который чувствует себя несколько контр-интуитивным. Я прошел через другие подобные сообщения в Stack Overflow, но было бы неплохо получить представление, специфичное для этого типа общего хранения сообщений.
Ответы
Ответ 1
-
TEXT
и BLOB
хранятся вне таблицы, а таблица просто имеет указатель на местоположение фактического хранилища.
-
VARCHAR
хранится в соответствии с таблицей. VARCHAR
быстрее, когда размер разумный, компромисс которого будет быстрее, зависит от ваших данных и вашего оборудования, вы хотите сравнить реальный сценарий с вашими данными.
Обновление Хранится ли VARCHAR
или TEXT
встроенным или вне записи, зависит от размера данных, размера столбцов, формата строки и версии MySQL. Это не зависит от "текста" против "varchar".
Ответ 2
Можете ли вы предсказать, как долго будет вводиться пользователь?
УАКСНАК (Х)
Дело: имя пользователя, адрес электронной почты, страна, тема, пароль
ТЕКСТ
Дело: сообщения, электронные письма, комментарии, форматированный текст, html, код, изображения, ссылки
MEDIUMTEXT
Дело: большие тела json, книги с малой длиной до средней длины, строки csv
LONGTEXT
Дело: учебники, программы, летние файлы журналов, Гарри Поттер и кубок огня, ведение научных исследований
Ответ 3
Просто для уточнения наилучшей практики:
-
Сообщения в текстовом формате почти всегда сохраняются как ТЕКСТ (они заканчиваются сколь угодно длинными)
-
Атрибуты String должны храниться как VARCHAR (имя пользователя-получателя, субъект и т.д.).
Я понимаю, что у вас есть предел переднего конца, и это здорово, пока это не так. * grin * Трюк состоит в том, чтобы думать о БД отдельно от приложений, которые подключаются к нему. Просто потому, что одно приложение ограничивает данные, это не означает, что данные ограничены по существу.
Что происходит с сообщениями, которые заставляют их не больше 3000 символов? Если это просто произвольное ограничение приложения (скажем, для текстового поля или что-то еще), используйте поле TEXT
на уровне данных.
Ответ 4
Отказ от ответственности: я не эксперт по MySQL... но это мое понимание проблем.
Я думаю, что TEXT хранится вне строки mysql, в то время как я думаю, что VARCHAR хранится как часть строки. Для строк mysql существует максимальная длина строки, поэтому вы можете ограничить количество других данных, которые вы можете сохранить в строке, используя VARCHAR.
Также из-за того, что VARCHAR является частью строки, я подозреваю, что запросы, смотрящие на это поле, будут немного быстрее, чем при использовании фрагмента TEXT.
Ответ 5
Краткий ответ: нет практического, производительности или хранения, разницы.
Длинный ответ:
По сути, нет никакой разницы (в 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()
основано на размере, а не на имени типа данных. Для обновленного обсуждения о включении/выключении хранения больших столбцов текста/больших двоичных объектов смотрите это.
Ответ 6
Предыдущие ответы недостаточно настаивают на главной проблеме: даже в очень простых запросах, таких как
(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.)
Ответ 7
Varchar для небольших данных, таких как адреса электронной почты, в то время как Text для гораздо больших данных, таких как новостные статьи, Blob для двоичных данных, таких как изображения.
Производительность Varchar более высокая, поскольку он полностью запускается из памяти, но это не будет иметь место, если данные слишком велики, как, например, varchar(4000)
.
Текст, с другой стороны, не прилипает к памяти и зависит от производительности диска, но этого можно избежать, разделив текстовые данные в отдельной таблице и применив запрос левого соединения для извлечения текстовых данных.
BLOB-объект намного медленнее, поэтому используйте его только в том случае, если у вас нет таких данных, как 10000 изображений, которые будут стоить 10000 записей.
Следуйте этим советам для максимальной скорости и производительности:
-
Используйте varchar для имени, названий, электронных писем
-
Используйте текст для больших данных
-
Отдельный текст в разных таблицах
-
Используйте запросы левого соединения для идентификатора, такого как номер телефона
-
Если вы собираетесь использовать Blob, примените те же советы, что и в текстовом.
Это приведет к тому, что запросы будут стоить миллисекунды для таблиц с данными> 10 МБ и гарантированным размером до 10 ГБ.
Ответ 8
Существует огромная разница между VARCHAR и TEXT. Хотя поля VARCHAR могут быть проиндексированы, поля TEXT - нет. Поля типа VARCHAR хранятся в строке, в то время как TEXT хранятся в автономном режиме, в записях фактически хранятся только указатели на данные TEXT.
Если вам нужно проиндексировать свое поле для более быстрого поиска, обновления или удаления, чем использовать VARCHAR, независимо от его размера. VARCHAR (10000000) никогда не будет таким же, как поле TEXT, потому что эти два типа данных различны по своей природе.
- Если вы используете свое поле только для архивации
- вы не заботитесь о скорости передачи данных
- Вы заботитесь о скорости, но вы будете использовать оператор "% LIKE%" в своем поисковом запросе, так что индексация не сильно поможет
- Вы не можете предсказать предел длины данных
чем перейти к тексту.