Frage MySQL: Große VARCHAR vs. TEXT?


Ich habe eine Nachrichtentabelle in MySQL, die Nachrichten zwischen Benutzern aufzeichnet. Abgesehen von den typischen IDs und Nachrichtentypen (alle Integer-Typen) muss ich den eigentlichen Nachrichtentext entweder als VARCHAR oder als TEXT speichern. Ich setze ein Front-End-Limit von 3000 Zeichen, was bedeutet, dass die Nachrichten niemals länger in die Datenbank eingefügt werden.

Gibt es einen Grund dafür, mit VARCHAR (3000) oder TEXT zu gehen? Es ist etwas, VARCHAR (3000) zu schreiben, das sich etwas kontra-intuitiv anfühlt. Ich habe andere ähnliche Beiträge in Stack Overflow durchgesehen, aber es wäre gut, Ansichten zu erhalten, die für diese Art der allgemeinen Nachrichtenspeicherung spezifisch sind.


758
2018-01-07 20:40


Ursprung


Antworten:


  • TEXT und BLOB wird außerhalb der Tabelle gespeichert, wobei die Tabelle nur einen Zeiger auf den Speicherort des tatsächlichen Speichers hat.

  • VARCHAR wird inline mit der Tabelle gespeichert. VARCHAR ist schneller, wenn die Größe vernünftig ist, der Kompromiss, der schneller wäre, hängt von Ihren Daten und Ihrer Hardware ab, Sie würden ein Realworld-Szenario mit Ihren Daten vergleichen.

Aktualisieren Ob VARCHAR oder TEXT wird inline gespeichert oder außerhalb der Aufzeichnung abhängig von der Datengröße, der Spaltengröße, dem row_format und der MySQL-Version. Es tut nicht abhängig von "text" vs "varchar".


759
2018-01-07 20:45



Können Sie vorhersagen, wie lange die Benutzereingaben dauern würden?

VARCHAR (X)

Fall: Benutzername, E-Mail, Land, Betreff, Passwort


TEXT

Fall: Nachrichten, E-Mails, Kommentare, formatierter Text, HTML, Code, Bilder, Links


MEDIUMTEXT

Fall: große json-Körper, kurze bis mittellange Bücher, csv-Strings


LONGTEXT

Fall: Lehrbücher, Programme, Jahre Protokolle Dateien, Harry Potter und den Feuerkelch, wissenschaftliche Forschung Protokollierung


415
2017-11-01 17:56



Nur um die beste Praxis zu klären:

  1. Nachrichten im Textformat sollten fast immer als TEXT gespeichert werden (am Ende sind sie beliebig lang)

  2. String-Attribute sollten als VARCHAR (der Zielbenutzername, der Betreff usw.) gespeichert werden.

Ich verstehe, dass Sie ein Front-End-Limit haben, das ist großartig, bis es nicht ist. * grins * Der Trick besteht darin, die DB als getrennt von den Anwendungen zu betrachten, die damit verbunden sind. Nur weil eine Anwendung die Daten begrenzt, bedeutet dies nicht, dass die Daten an sich begrenzt sind.

Was bringt die Nachrichten selbst dazu, dass sie niemals mehr als 3000 Zeichen haben? Wenn es sich nur um eine willkürliche Anwendungsbeschränkung handelt (z. B. für ein Textfeld oder etwas), verwenden Sie a TEXT Feld auf der Datenschicht.


210
2018-01-07 21:53



Disclaimer: Ich bin kein MySQL-Experte ... aber das ist mein Verständnis der Probleme.

Ich denke, TEXT ist außerhalb der MySQL-Zeile gespeichert, während ich denke, dass VARCHAR als Teil der Zeile gespeichert ist. Es gibt eine maximale Zeilenlänge für mysql rows. Sie können also begrenzen, wie viele andere Daten Sie in einer Zeile speichern können, indem Sie VARCHAR verwenden.

Auch aufgrund der Tatsache, dass VARCHAR einen Teil der Zeile bildet, vermute ich, dass Abfragen, die auf dieses Feld schauen, etwas schneller sind als solche, die einen TEXT-Block verwenden.


31
2018-01-07 20:47



Kurze Antwort:  Kein praktischer Unterschied, Performance oder Speicher.

Lange Antwort:

Es gibt im Wesentlichen keinen Unterschied (in MySQL) zwischen VARCHAR(3000) (oder irgendein anderes großes Limit) und TEXT. Ersteres wird bei 3000 abgeschnitten Figuren; Letzteres wird bei 65535 abgeschnitten Bytes. (Ich unterscheide zwischen Bytes und Figuren weil ein Zeichen mehrere Bytes aufnehmen kann.)

Für kleinere Grenzen in VARCHAREs gibt einige Vorteile gegenüber TEXT.

  • "kleiner" bedeutet 191, 255, 512, 767 oder 3072 usw., abhängig von Version, Kontext und CHARACTER SET.
  • INDEXes sind begrenzt, wie groß eine Spalte indiziert werden kann. (767 oder 3072 Bytes; das ist Version und Einstellungen abhängig)
  • Zwischentabellen erstellt von komplex SELECTs werden auf zwei verschiedene Arten behandelt - MEMORY (schneller) oder MyISAM (langsamer). Wenn "große" Spalten beteiligt sind, wird die langsamere Technik automatisch ausgewählt. (Wesentliche Änderungen in Version 8.0; daher kann dieser Aufzählungspunkt Änderungen unterliegen.)
  • Bezogen auf den vorherigen Artikel, alle TEXT Datentypen (im Gegensatz zu VARCHAR) Springe direkt zu MyISAM. Das ist, TINYTEXT ist für generierte temporäre Tabellen automatisch schlechter als das Äquivalent VARCHAR. (Aber das nimmt die Diskussion in eine dritte Richtung!)
  • VARBINARY ist wie VARCHAR; BLOB ist wie TEXT.

Widerlegung auf andere Antworten

Die ursprüngliche Frage fragte eine Sache (welcher Datentyp zu verwenden); die angenommene Antwort beantwortet etwas anderes (Off-Record-Speicher). Diese Antwort ist jetzt veraltet.

Wenn dieser Thread gestartet wurde und beantwortet, es gab nur zwei "Zeilenformate" in InnoDB. Bald danach, zwei weitere Formate (DYNAMIC und COMPRESSES) wurden vorgestellt.

Der Speicherort für TEXT und VARCHAR() basiert auf Größe, nicht auf Name des Datentyps. Für ein aktualisiert Diskussion über das Speichern von großen Text / Blob-Spalten auf / aus dem Speicher, siehe Dies .


3
2018-06-25 16:05



Die vorhergehenden Antworten bestehen nicht genug auf das Hauptproblem: selbst in sehr einfachen Abfragen (SELECT t2. * FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) kann eine temporäre Tabelle benötigt werden, und wenn ein VARCHAR-Feld beteiligt ist, wird es in ein CHAR-Feld in der temporären Tabelle konvertiert. Wenn Sie in Ihrer Tabelle also 500.000 Zeilen mit einem VARCHAR (65000) -Feld angeben, wird diese Spalte allein 6.5 * 5 * 10 ^ 9 Byte verwenden. Solche temporären Tabellen können nicht im Speicher verarbeitet werden und werden auf die Festplatte geschrieben. Die Auswirkungen können katastrophal sein.

Quelle (mit Metriken): https://nicj.net/mysql-text-vs-varchar-performance/ (Dies bezieht sich auf die Behandlung von TEXT vs VARCHAR in "Standard" (?) MyISAM Speicher-Engine. Es kann in anderen, z. B. InnoDB anders sein.)


1
2018-06-30 21:43