MySQL: Large VARCHAR vs. TEXT?

Mam tabelę wiadomości w MySQL, która rejestruje wiadomości między użytkownikami. Oprócz typowych identyfikatorów i typów wiadomości (Wszystkie typy integer) muszę zapisać tekst wiadomości jako VARCHAR lub TEXT. Ustawiam limit front-end 3000 znaków, co oznacza, że wiadomości nigdy nie będą wstawiane do db jako dłuższe niż to.

Czy jest jakiś powód, by używać VARCHAR (3000) lub TEXT? Jest coś w samym pisaniu VARCHAR (3000) co wydaje się nieco intuicyjne. Przeglądałem inne podobne posty na Stack Overflow, ale byłoby dobrze, aby uzyskać widoki specyficzne dla tego typu wspólnego przechowywania wiadomości.

Author: Benjamin, 2010-01-07

6 answers

  • TEXT i BLOB jest przechowywana poza tabelą, a tabela ma tylko wskaźnik do lokalizacji faktycznego magazynu.

  • VARCHAR jest przechowywany w wierszu tabeli. VARCHAR jest szybszy, gdy rozmiar jest rozsądny, którego wymiana będzie szybsza zależy od Twoich danych i sprzętu, chciałbyś porównać scenariusz realny ze swoimi danymi.

Update to, czy VARCHAR lub TEXT jest przechowywane w linii, czy poza rekordem, zależy od wielkości danych, rozmiar kolumn, row_format i wersja MySQL. To nie zależy od "text" vs "varchar".

 769
Author: MindStalker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-25 16:12:32

Czy możesz przewidzieć, jak długo będzie wejście użytkownika?

VARCHAR (X)

Case: nazwa użytkownika, e-mail, kraj, temat, hasło


Tekst

Case: wiadomości, e-maile, komentarze, sformatowany tekst, html, kod, obrazy, linki


MEDIUMTEXT

Etui: Duże korpusy json, krótkie do średniej długości książki, ciągi csv


LONGTEXT

Case: podręczniki, programy, pliki z dzienników, harry potter i Czara Ognia, rejestr badań naukowych

 422
Author: Michael J. Calkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 15:16:46

Dla wyjaśnienia najlepszych praktyk:

  1. Wiadomości w formacie tekstowym powinny być prawie zawsze zapisywane jako tekst (ostatecznie są arbitralnie Długie)

  2. Atrybuty łańcuchowe powinny być przechowywane jako VARCHAR (nazwa użytkownika docelowego, temat, itd...).

Rozumiem, że masz limit front end, który jest świetny, dopóki nie jest. * grin * sztuczka polega na tym, aby myśleć o DB jako oddzielnym od aplikacji, które się z nim łączą. Tylko dlatego, że jeden aplikacja nakłada ograniczenie na dane, nie oznacza to, że dane są wewnętrznie ograniczone.

Co jest takiego w samych wiadomościach, że zmusza ich do tego, aby nigdy nie były więcej niż 3000 znaków? Jeśli jest to tylko dowolne ograniczenie aplikacji (np. dla pola tekstowego lub czegoś takiego), użyj pola TEXT na warstwie danych.

 212
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 20:00:44

Zastrzeżenie: nie jestem ekspertem MySQL ... ale to jest moje zrozumienie problemów.

Myślę, że tekst jest przechowywany poza wierszem mysql, podczas gdy myślę, że VARCHAR jest przechowywany jako część wiersza. Istnieje maksymalna długość wierszy dla wierszy mysql .. możesz więc ograniczyć ilość innych danych, które możesz przechowywać w wierszu, używając VARCHAR.

Również ze względu na to, że VARCHAR jest częścią wiersza, podejrzewam, że zapytania patrząc na to pole będą nieco szybsze niż te, które używają fragmentu tekstu.

 31
Author: Michael Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:47:02

Krótka odpowiedź: brak praktycznej, wydajnościowej lub magazynowej różnicy.

Długa odpowiedź:

Zasadniczo nie ma różnicy (w MySQL) między VARCHAR(3000) (lub jakimkolwiek innym dużym limitem) a TEXT. Pierwszy z nich zostanie skrócony o 3000 znaków; drugi zostanie skrócony o 65535 bajtów. (Rozróżniam bajty i znaki , ponieważ znak może przyjmować wiele bajtów.)

Dla mniejszych limity w VARCHAR, są pewne zalety w stosunku do TEXT.

    W zależności od wersji, kontekstu i CHARACTER SET," mniejszy " oznacza 191, 255, 512, 767 lub 3072 itd.
  • INDEXes są ograniczone w tym, jak duża kolumna może być indeksowana. (767 lub 3072 bajtów ; jest to zależne od wersji i ustawień)
  • tabele pośrednie tworzone przez complex SELECTs są obsługiwane na dwa różne sposoby-pamięć (szybsza) lub MyISAM (wolniejsza). Gdy w grę wchodzą "duże" kolumny, wolniejsza technika jest automatycznie wybierane. (Znaczące zmiany w wersji 8.0; więc ten punkt może ulec zmianie.)
  • powiązane z poprzednią pozycją, wszystkie TEXT typy danych (w przeciwieństwie do VARCHAR) przeskakują prosto do MyISAM. Oznacza to, że {[9] } jest automatycznie gorsze dla generowanych tabel temp niż odpowiednik VARCHAR. (Ale to prowadzi dyskusję w trzecim kierunku!)
  • VARBINARY jest jak VARCHAR; BLOB jest jak TEXT.

Odrzucenie innych odpowiedzi

The oryginalne pytanie zadało jedno (jakiego typu danych użyć); zaakceptowana odpowiedź odpowiadała na coś innego (zapis nieoficjalny). Ta odpowiedź jest już nieaktualna.

Kiedy ten wątek został uruchomiony i odpowiedział, w InnoDB były tylko dwa "formaty wierszy". Wkrótce potem wprowadzono dwa kolejne formaty (DYNAMIC i COMPRESSES).

Miejsce przechowywania dla TEXT i VARCHAR() jest oparte na Rozmiar, a nie na nazwa typu danych. Dla zaktualizowano omówienie zapisu na / poza zapisem dużych kolumn tekstowych / blobowych, patrz to .

 8
Author: Rick James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-23 18:22:02

Poprzednie odpowiedzi nie nalegają wystarczająco na główny problem: nawet w bardzo prostych zapytaniach, takich jak

(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) 

Może być wymagana tabela tymczasowa, a jeśli wymagane jest pole VARCHAR, jest ono konwertowane na pole CHAR w tabeli tymczasowej. Więc jeśli masz w tabeli powiedzmy 500 000 wierszy z polem VARCHAR(65000), to tylko ta kolumna użyje 6.5*5*10^9 bajt. Takie tabele temp nie mogą być obsługiwane w pamięci i są zapisywane na dysk. Można się spodziewać, że skutki katastrofa.

Źródło (z metrykami): https://nicj.net/mysql-text-vs-varchar-performance / (Odnosi się to do obsługi TEXT vs VARCHAR w "standardzie"(?) MyISAM storage engine. Może być inaczej w innych, np. InnoDB.)

 2
Author: Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-23 21:06:29