Maksymalne rozmiary pamięci TINYTEXT, TEXT, MEDIUMTEXT i LONGTEXT

796

Według dokumentów MySQL istnieją cztery typy TEKSTÓW:

  1. TINYTEXT
  2. TEKST
  3. MEDIUMTEXT
  4. LONGTEXT

Jaka jest maksymalna długość, którą mogę zapisać w kolumnie każdego typu danych, zakładając, że kodowanie znaków to UTF-8?

Lalith B.
źródło
26
Weźmy na przykład typ TEKST. Może zawierać 65535 bajtów danych. UTF-8 zawiera znaki wielobajtowe. Dlatego, jeśli wypełniłeś pole tylko duńskim znakiem „Ø”, otrzymasz tylko 32767 znaków, ponieważ ten znak UTF-8 składa się z dwóch bajtów. Jeśli wypełnisz go „a”, otrzymasz 65535 znaków.
Andrew Plank,
1
Zastanów się
Somnath Muluk

Odpowiedzi:

1518

Z dokumentacji :

      Wpisz | Maksymalna długość
----------- + -------------------------------------
  TINYTEXT | 255 (2 8 -1) bajtów
      TEKST | 65,535 (2 16 1) bajtów = 64 KiB
ŚREDNIOTekst | 16777215 (2 24 1) bajtów = 16 MiB
  LONGTEXT | 4294967295 (2 32 -1) = 4 bajty GiB

Pamiętaj, że liczba znaków, które można zapisać w kolumnie, będzie zależeć od kodowania znaków .

Most
źródło
3
@Bridge Nie wiem, czy rozumiem, ale to oznacza, że ​​TINYTEXT może uzyskać do 255 znaków, prawda?
ltdev
9
@Lykos Tak, cóż - w zależności od postaci. Z dokumentacji: 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.więcej szczegółów można znaleźć w odpowiedzi Ankana.
Most
4
@ aurel.g W ten sposób naprawdę odpowiadasz na pytanie. I zgadzam się z Christophe'em, tak mySQL powinien prezentować swoje parametry - nawet jeśli jest to jedynie skrót od ich ... tajemnego widoku tekstu.
cbmtrx,
1
Warto dodać, że rząd wielkości znaku to kilka bajtów (chyba 1). Można więc przechowywać 10 000-50 000 znaków w kolumnie TEKST ...
Vince
30
Dlaczego trudniej jest znaleźć to w dokumentacji niż w
przepełnieniu stosu
245

Rozszerzenie tej samej odpowiedzi

  1. Ten post SO szczegółowo opisuje koszty ogólne i mechanizmy przechowywania.
  2. Jak zauważono w punkcie (1), zawsze należy używać VARCHAR zamiast TINYTEXT. Jednak przy użyciu VARCHAR maksymalny rozmiar wierszy nie powinien przekraczać 65535 bajtów.
  3. Jak opisano tutaj http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html , maksymalnie 3 bajty dla utf-8.

TO SZABLONY TABELA SZACUNKOWA DO SZYBKICH DECYZJI!

  1. Więc najgorsze założenia (3 bajty na znak utf-8) do najlepszego przypadku (1 bajt na znak utf-8)
  2. Zakładając, że język angielski ma średnio 4,5 litery na słowo
  3. x to liczba przydzielonych bajtów

xx

      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

Proszę również odnieść się do odpowiedzi Chrisa V.: https://stackoverflow.com/a/35785869/1881812

Ankan-Zerob
źródło
4
Jakie jest uzasadnienie tego „VARCHAR powinien zawsze być używany zamiast TINYTEXT”? Czy nie byłoby lepiej (ponieważ bardziej efektywnie przechowywać) czasami korzystać z mniejszego TINYTEXT?
vlasits
24
@vlasits przeczytał dołączony post SO, aby uzyskać szczegółowe informacje. (1) wszystkie typy tekstu, w tym tekst tytynowy, są przechowywane jako obiekty poza wierszem, który jest jednym narzutem (2) Do tych obiektów odwołuje się następnie adres 8 lub 16 bajtów. więc bez względu na to, jak mały jest twój tinytext, dodajesz niepotrzebne koszty ogólne, które również dla maksymalnego rozmiaru 255 bajtów. jasne jest, że należy zastosować varchar, który nie będzie miał żadnego z powyższych kosztów ogólnych.
Ankan-Zerob
4
@ Ankan-Zerob Biorąc pod uwagę, że wydaje się bardzo jasne, że TINYTEXT nigdy nie powinien być używany w VARCHAR, jakie jest uzasadnienie, aby mieć go jako opcję? Czy istnieje jakiś niejasny przypadek użycia, w którym jest to konieczne?
nextgentech
4
@nextgentech Zajrzyj na dev.mysql.com/doc/refman/5.0/en/column-count-limit.html . Rozmiar rekordu jest ograniczony do 64 KiB. Tabela jest ograniczona do 4k kolumn. A TINYTEXTliczy 1 bajt + 8 bajtów w stosunku do wielkości rekordu, podczas gdy VARCHAR(255)od 1 bajtu + 255 bajtów do 2 bajtów + 1020 bajtów (4 bajty UTF-8 znaków) w stosunku do wielkości rekordu.
Shi
2
Lubię wyrażać wielkości pól w słowach, ale ... angielski zwykle ma około 5 znaków na słowo, a do zapisania jest też spacja; jednak angielski zawsze będzie miał prawie 1 bajt na znak UTF-8, więc podzieliłbym przez 6, dając około 40/10 000/2 700 000/710 000 000 słów dla różnych rozmiarów. Języki z dużą ilością akcentów, takie jak polski, miałyby nieco mniej słów; Grecki, hebrajski, arabski itp. (Głównie sekwencje 2-bajtowe) około połowy; Ideogramy CJK to sekwencje 3 lub 4 bajtowe, ale nie wiem, jak długie są słowa.
ChrisV
44

Przechodząc do wyzwania @ Ankan-Zerob, oto moja ocena maksymalnej długości, jaką można zapisać w każdym typie tekstu mierzonej słowami :

      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

W języku angielskim 4,8 liter na słowo jest prawdopodobnie dobrą średnią (np. Norvig.com/mayzner.html ), chociaż długości słów będą się różnić w zależności od dziedziny (np. Język mówiony vs. artykuły naukowe), więc nie ma sensu być zbyt precyzyjnym. Angielski to w większości jednobajtowe znaki ASCII, z bardzo sporadycznymi wielobajtowymi znakami, tak zbliżonymi do jednego bajtu na literę. Dodatkowy znak musi być dozwolony dla spacji między słowami, więc zaokrągliłem w dół z 5,8 bajtów na słowo. Języki z dużą ilością akcentów, takie jak np. Polski, przechowują nieco mniej słów, podobnie jak np. Niemiecki z dłuższymi słowami.

Języki wymagające znaków wielobajtowych, takie jak grecki, arabski, hebrajski, hindi, tajski itp., Zazwyczaj wymagają dwóch bajtów na znak w UTF-8. Szaleńczo zgadując przy 5 literach na słowo, zaokrągliłem w dół z 11 bajtów na słowo.

Skrypty CJK (Hanzi, Kanji, Hiragana, Katakana itp.) Nic nie wiem; Uważam, że znaki w UTF-8 wymagają w większości 3 bajtów i (z ogromnym uproszczeniem) można by rozważyć użycie około 2 znaków na słowo, więc byłyby gdzieś pomiędzy pozostałymi dwoma. (Skrypty CJK prawdopodobnie wymagają mniej pamięci przy użyciu UTF-16).

To oczywiście ignoruje koszty ogólne związane z przechowywaniem itp.

ChrisV
źródło
Znaki CJK mogą używać sekwencji 3 lub 4 bajtów: dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8.html
Raptor
8

To miłe, ale nie odpowiada na pytanie:

„Zamiast TINYTEXT należy zawsze używać VARCHAR.” Tinytext jest przydatny, jeśli masz szerokie wiersze - ponieważ dane są przechowywane poza rekordem. Istnieje narzut związany z wydajnością, ale ma on zastosowanie.

colin0117
źródło