Максимальные размеры хранилища TINYTEXT, TEXT, MEDIUMTEXT и LONGTEXT

796

Согласно документации по MySQL , существует четыре типа TEXT:

  1. TINYTEXT
  2. ТЕКСТ
  3. MEDIUMTEXT
  4. LONGTEXT

Какова максимальная длина, которую я могу хранить в столбце каждого типа данных, предполагая, что кодировка символов - UTF-8?

Лалит Б
источник
26
Взять, к примеру, тип TEXT. Он может содержать 65535 байт данных. UTF-8 содержит многобайтовые символы. Следовательно, если вы заполните поле, используя только датский символ «Ø», вы получите только 32767 символов, поскольку этот символ UTF-8 состоит из двух байтов. Если вы заполните его буквой «а», вы получите 65535 символов.
Эндрю Планк
1
Также подумайте о том, какой тип данных лучше использовать TEXT или VARCHAR
Сомнат Мулук

Ответы:

1518

Из документации :

      Тип | Максимальная длина
----------- + -------------------------------------
  TINYTEXT | 255 (2 8 -1) байтов
      ТЕКСТ | 65 535 (2 16 -1) байт = 64 КиБ
MEDIUMTEXT | 16 777 215 (2 24 -1) байт = 16 МБ
  LONGTEXT | 4 294 967 295 (2 32 -1) байт = 4 ГиБ

Обратите внимание, что количество символов, которое можно сохранить в столбце, будет зависеть от кодировки символов .

Мост
источник
3
@ Бридж Не уверен, что я понимаю, но это означает, что TINYTEXT может получить до 255 символов, я прав?
января
9
@ Lykos Да, хорошо - в зависимости от персонажей. Из документации: A TEXT column with a maximum length of 255 (28 – 1) characters. The effective maximum length is less if the value contains multi-byte characters.см. Ответ Анкана для более подробной информации.
Мост
4
@ aurel.g Вот так ты и отвечаешь на вопрос. И я согласен с Кристофом, именно так mySQL должен представлять свои параметры - даже если это просто сокращение от их ... загадочного текстового представления.
cbmtrx
1
Возможно, стоит добавить, что порядок величины символа составляет пару байтов (я полагаю, мин. 1). Таким образом, можно хранить 10 000-50 000 символов в столбце ТЕКСТ, ...
Винс
30
Почему это труднее найти в документах, чем в
стеке потока
245

Расширение того же ответа

  1. Этот пост SO подробно описывает накладные расходы и механизмы хранения.
  2. Как отмечено в пункте (1), VARCHAR всегда должен использоваться вместо TINYTEXT. Однако при использовании VARCHAR максимальный размер строки не должен превышать 65535 байтов.
  3. Как описано здесь http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html , максимум 3 байта для utf-8.

ЭТО ЖЕСТКИЙ СТОЛ ОЦЕНКИ ДЛЯ БЫСТРОГО РЕШЕНИЯ!

  1. Таким образом, предположения наихудшего случая (3 байта на символ utf-8) лучше всего (1 байт на символ utf-8)
  2. Предполагая, что английский язык имеет в среднем 4,5 буквы на слово
  3. х количество выделенных байтов

хх

      Type | A= worst case (x/3) | B = best case (x) | words estimate (A/4.5) - (B/4.5)
-----------+---------------------------------------------------------------------------
  TINYTEXT |              85     | 255               | 18 - 56
      TEXT |          21,845     | 65,535            | 4,854.44 - 14,563.33  
MEDIUMTEXT |       5,592,415     | 16,777,215        | 1,242,758.8 - 3,728,270
  LONGTEXT |   1,431,655,765     | 4,294,967,295     | 318,145,725.5 - 954,437,176.6

Пожалуйста, обратитесь к ответу Криса V также: https://stackoverflow.com/a/35785869/1881812

Ankan-Zerob
источник
4
Каково обоснование для этого «VARCHAR всегда должен использоваться вместо TINYTEXT»? Разве не было бы лучше (потому что более эффективно использовать хранилище) иногда использовать меньший TINYTEXT?
власит
24
@vlasits прочитайте включенный SO сообщение для деталей. (1) все типы текста, включая крошечный текст, хранятся как объекты вне строки, которая занимает одну служебную информацию (2) Затем на эти объекты ссылаются адреса 8 или 16 байтов. поэтому независимо от того, насколько крошечен ваш крошечный текст, вы добавляете ненужные накладные расходы, что тоже для максимального размера 255 байт. Понятно, что следует использовать varchar, который не будет иметь каких-либо из перечисленных выше издержек.
Анкан-Зероб
4
@ Ankan-Zerob Принимая во внимание, что совершенно очевидно, что TINYTEXT никогда не следует использовать поверх VARCHAR, в чем смысл даже использовать его в качестве опции? Есть ли какой-то неясный сценарий использования, где это необходимо?
nextgentech
4
@nextgentech Посмотрите на dev.mysql.com/doc/refman/5.0/en/column-count-limit.html . Размер записи ограничен 64 КиБ. Таблица ограничена 4k столбцами. A TINYTEXTсчитает 1 байт + 8 байт от размера записи, тогда как a VARCHAR(255)считает от 1 байта + 255 байт до 2 байт + 1020 байт (4 байта символов UTF-8) против размера записи.
Ши
2
Мне нравится выражать размеры полей в словах, но ... обычно считается, что в английском языке содержится около 5 символов на слово, а также есть пробел, который нужно сохранить; тем не менее, английский всегда будет близок к 1 байту на символ UTF-8, поэтому я бы разделил на 6, получив около 40/10 000/2 700 000/710 000 000 слов для разных размеров. В языках с большим количеством акцентов, таких как польский, было бы немного меньше слов; Греческий, иврит, арабский и т. Д. (В основном 2-байтовые последовательности) около половины; Идеограммы CJK представляют собой 3- или 4-байтовые последовательности, но я не знаю, каковы длинные слова.
ChrisV
44

Подходя к задаче @ Ankan-Zerob, это моя оценка максимальной длины, которую можно сохранить в каждом типе текста, измеряемом словами :

      Type |         Bytes | English words | Multi-byte words
-----------+---------------+---------------+-----------------
  TINYTEXT |           255 |           ±44 |              ±23
      TEXT |        65,535 |       ±11,000 |           ±5,900
MEDIUMTEXT |    16,777,215 |    ±2,800,000 |       ±1,500,000
  LONGTEXT | 4,294,967,295 |  ±740,000,000 |     ±380,000,000

В английском языке 4,8 буквы на слово, вероятно, являются хорошим средним значением (например, norvig.com/mayzner.html ), хотя длина слова будет варьироваться в зависимости от предметной области (например, разговорный язык или академические работы), поэтому нет смысла быть слишком точным. Английский - это в основном однобайтовые символы ASCII, с очень редкими многобайтовыми символами, которые близки к одному байту на букву. Для межсловных пробелов должен быть разрешен дополнительный символ, поэтому я округлил с 5,8 байта на слово. Языки с большим количеством акцентов, такие как, скажем, польский, будут хранить немного меньше слов, как, например, немецкий с более длинными словами.

Для языков, требующих многобайтовых символов, таких как греческий, арабский, иврит, хинди, тайский и т. Д. И т. Д., Обычно требуется два байта на символ в UTF-8. Угадывая по 5 букв на слово, я округлил с 11 байтов на слово.

Сценарии CJK (ханзи, кандзи, хирагана, катакана и т. Д.), О которых я ничего не знаю; Я полагаю, что символам в UTF-8 в основном требуется 3 байта, и (с огромным упрощением) они могут использовать около 2 символов в слове, поэтому они будут где-то между двумя другими. (Сценарии CJK, вероятно, потребуют меньше памяти при использовании UTF-16, в зависимости от).

Это, конечно, игнорирование накладных расходов на хранение и т. Д.

ChrisV
источник
Символы CJK могут использовать 3 или 4-байтовую последовательность: dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8.html
Raptor
8

Это хорошо, но не отвечает на вопрос:

«VARCHAR всегда должен использоваться вместо TINYTEXT». Tinytext полезен, если у вас широкие строки - поскольку данные хранятся вне записи. Производительность снижается, но она имеет смысл.

colin0117
источник