Was ist der Unterschied zwischen den Datentypen MySQL VARCHAR und TEXT?

19

Gibt es nach Version 5.0.3 (die es VARCHAR ermöglichte, 65.535 Byte zu groß zu werden und keine nachgestellten Leerzeichen mehr zu kürzen) einen wesentlichen Unterschied zwischen diesen beiden Datentypen?

Ich habe die Liste der Unterschiede gelesen und die einzigen zwei sind:

Für Indizes für BLOB- und TEXT-Spalten müssen Sie eine Indexpräfixlänge angeben. Für CHAR und VARCHAR ist eine Präfixlänge optional. Siehe auch Abschnitt 7.5.1, „Spaltenindizes“.

und

BLOB- und TEXT-Spalten dürfen keine DEFAULT-Werte enthalten.

Warum sollten Sie den Datentyp TEXT aufgrund dieser beiden Einschränkungen über varchar (65535) verwenden? Gibt es Performance-Konsequenzen übereinander?

Derek Downey
quelle
1
Wann möchten Sie mehr als 65535 Zeichen in den Daten?
BlackICE
Hier ist ein ziemlich guter Forenthread über Benchmarks zwischen varchar und text: http://forums.mysql.com/read.php?24,105964,105964
geteilt am
Da die Liste dort wirklich gute Arbeit darin leistet, die expliziten Details darzustellen, und weil Sie bereits die aufgezählten Unterschiede aufgelistet haben, bin ich mir nicht sicher, ob dies die Art von Frage ist, die wir für DBA benötigen. Gibt es einen Grund, warum die von Ihnen angegebene Liste und die Gründe, die Sie angegeben haben , in diesem Fall nicht gut genug sind? Ansonsten gehe ich zu VtC
jcolebrand
1
Ich habe meine Frage aktualisiert, aber ein offensichtlicher Grund, bei dem ich mir nicht sicher bin, ist die Leistung von einer über die andere. Nicht sicher, ob es andere nicht so offensichtliche Gründe gibt
Derek Downey
Ist es also fair, dass Sie die Leistungsmerkmale der einen über die anderen stellen?
jcolebrand

Antworten:

13

geteilt, verbunden mit einigen Informationen, die das Grundproblem erklären (es gibt Leistungsunterschiede), aber es ist nicht einfach genug zu sagen, dass man immer besser ist als der andere. (Andernfalls gibt es keinen Grund, beides zu haben.) In MyISM ist die maximale Größe von 64 KB für VARCHAR nicht pro Feld, sondern pro Datensatz.

Grundsätzlich gibt es vier Möglichkeiten, Zeichenfolgen in Datenbankeinträgen zu speichern:

  1. feste Länge
  2. Zeichenfolgen im C-Stil (am Ende der Zeichenfolge mit NULL oder einem ähnlichen Zeichen gekennzeichnet)
  3. Pascal-Zeichenfolgen (ein paar Bytes zur Angabe der Länge, dann die Zeichenfolge)
  4. Zeiger (speichern Sie den String an einer anderen Stelle)

MyISM verwendet für VARCHAR einen ähnlichen Ansatz wie # 3 und für TEXT einen Hybridansatz, bei dem der Anfang der Zeichenfolge im Datensatz und der Rest der Zeichenfolge an einer anderen Stelle gespeichert werden. InnoDB ist ähnlich wie VARCHAR, speichert jedoch das gesamte TEXT-Feld außerhalb des Datensatzes.

Bei 1 & 4 ist das Zeug in der Aufzeichnung immer gleich lang, so dass es einfacher ist, zu überspringen, wenn Sie die Zeichenfolge nicht benötigen, aber danach brauchen. Sowohl # 2 als auch # 3 sind nicht schlecht für kurze Saiten ... # 2 muss weiter nach dem Marker suchen, während # 3 weiterspringen kann ... wenn die Saiten länger werden, wird # 2 für diese spezielle Verwendung schlechter Fall.

Wenn Sie die Zeichenfolge tatsächlich lesen müssen, ist # 4 langsamer, da Sie den Datensatz lesen müssen. Lesen Sie dann die Zeichenfolge, die möglicherweise an anderer Stelle auf der Festplatte gespeichert ist, je nachdem, wie diese Datenbank damit umgeht. Nummer 1 ist immer ziemlich einfach, und wieder treten ähnliche Probleme auf, bei denen Nummer 2 umso schlechter wird, je länger die Saite ist, während Nummer 3 bei sehr kleinen Saiten etwas schlechter ist als Nummer 2, aber umso besser, je länger die Saite wird.

Dann gibt es Speicheranforderungen ... # 1 ist immer eine feste Länge, daher kann es zu Aufblähungen kommen, wenn die meisten Zeichenfolgen nicht die maximale Länge haben. # 2 hat 1 zusätzliches Byte; # 3 hat normalerweise 2 zusätzliche Bytes bei einer maximalen Länge von 255, 4 zusätzliche Bytes bei einer maximalen Länge von 64 KB. # 4 hat die Zeigerlänge plus die Regeln für # 3 in der Regel.

Für die spezifischen Implementierungen in MySQL 5.1 heißt es in den Dokumenten für MyISM :

  • Unterstützung für einen echten VARCHAR-Typ; Eine VARCHAR-Spalte beginnt mit einer Länge, die in ein oder zwei Bytes gespeichert ist.
  • Tabellen mit VARCHAR-Spalten können eine feste oder dynamische Zeilenlänge haben.
  • Die Summe der Längen der VARCHAR- und CHAR-Spalten in einer Tabelle kann bis zu 64 KB betragen.

Während für InnoDB :

  • Der Teil mit variabler Länge des Datensatzkopfs enthält einen Bitvektor zum Anzeigen von NULL-Spalten. Wenn die Anzahl der Spalten im Index NULL sein kann, belegt der Bitvektor CEILING (N / 8) Bytes. (Wenn beispielsweise 9 bis 15 Spalten NULL sein können, verwendet der Bitvektor zwei Bytes.) Spalten, die NULL sind, belegen keinen anderen Platz als das Bit in diesem Vektor. Der Teil der Kopfzeile mit variabler Länge enthält auch die Längen der Spalten mit variabler Länge. Jede Länge nimmt ein oder zwei Bytes in Anspruch, abhängig von der maximalen Länge der Spalte. Wenn alle Spalten im Index NICHT NULL sind und eine feste Länge haben, enthält der Datensatzkopf keinen Teil mit variabler Länge.
  • Für jedes Feld mit variabler Länge, das nicht NULL ist, enthält der Datensatzkopf die Länge der Spalte in ein oder zwei Bytes. Zwei Bytes werden nur benötigt, wenn ein Teil der Spalte extern in Überlaufseiten gespeichert ist oder die maximale Länge 255 Bytes und die tatsächliche Länge 127 Bytes überschreitet. Für eine extern gespeicherte Spalte gibt die Zwei-Byte-Länge die Länge des intern gespeicherten Teils plus den 20-Byte-Zeiger auf den extern gespeicherten Teil an. Der interne Teil ist 768 Bytes, die Länge beträgt also 768 + 20. Der 20-Byte-Zeiger speichert die wahre Länge der Spalte.

...

Wenn Sie sich nicht sicher sind, was für Ihre Anforderungen am besten ist, sollten Sie, wie bei so vielen anderen Dingen im Umgang mit Datenbanken, versuchen, das Benchmarking mit ähnlichen Daten und Nutzungsdaten durchzuführen und deren Verhalten zu überprüfen.

Joe
quelle
Der untergliederte verknüpfte Thread besagt, dass MySQL Blobs und Textfelder inline inforums.mysql.com/read.php?24,105964,267596#msg-267596
Michael Mior
1
Nitpick ... Für alle praktischen Zwecke gibt es in keiner Engine eine 64-KB-Beschränkung für eine Zeile. LONGTEXTund LONGBLOBsind ein typisches Beispiel. Strings im C-Stil werden von MySQL nirgends verwendet (was mir bekannt ist). InnoDB verwendet einen hybriden Ansatz, der jedoch je nach Zeilengröße, Zeilenformat usw. komplexer ist. Das Speichern von Zeichenfolgen in "fester" Länge ist so gut wie nie ratsam, es sei denn, sie haben tatsächlich eine konstante Länge (country_code, zip_code usw.). . InnoDB hat 4 ROW_FORMATs; Der Text behandelt nur 1 oder 2 von ihnen.
Rick James
2

Wenn ein SELECT eine temporäre Tabelle erstellen muss (z. B. um die Ergebnisse zu sortieren), wird entweder eine MEMORY-Tabelle oder eine MyISAM-Tabelle erstellt. MEMORY ist effizienter. Es gibt Einschränkungen für MEMORY - man darf TEXT und BLOB nicht zulassen. Daher kann ein SELECT kann langsamer ausgeführt mit TEXT als VARCHAR.

Rick James
quelle