Qual è la differenza tra i tipi di dati MySQL VARCHAR e TEXT?


19

Dopo la versione 5.0.3 (che ha consentito a VARCHAR di essere 65.535 byte e ha smesso di troncare gli spazi finali), c'è qualche grande differenza tra questi due tipi di dati?

Stavo leggendo l' elenco delle differenze e le uniche due note sono:

Per gli indici su colonne BLOB e TEXT, è necessario specificare una lunghezza del prefisso indice. Per CHAR e VARCHAR, la lunghezza di un prefisso è facoltativa. Vedere la Sezione 7.5.1, "Indici di colonna".

e

Le colonne BLOB e TEXT non possono avere valori DEFAULT.

Quindi, a causa di queste due limitazioni sul tipo di dati TEXT, perché dovresti usarlo su varchar (65535)? Ci sono conseguenze sull'una sull'altra?


1
quando vuoi più di 65535 caratteri nei dati?
BlackICE,

Ecco un thread del forum piuttosto buono sui benchmark tra varchar e testo: http://forums.mysql.com/read.php?24,105964,105964
diviso il

Perché l'elenco lì fa davvero un buon lavoro nel definire i dettagli espliciti, e poiché hai già l'elenco elencato delle differenze, non sono sicuro che questo sia il tipo di domanda di cui abbiamo bisogno su DBA. C'è una ragione per cui l'elenco che hai citato e le ragioni che hai indicato non sono abbastanza buone in questo caso? Altrimenti vado a VtC
jcolebrand

1
Ho aggiornato la mia domanda, ma un ovvio motivo per cui non sono sicuro è la prestazione dell'uno sull'altro. Non sono sicuro se ci sono altri motivi non così ovvi
Derek Downey il

Quindi è giusto che ciò che stai chiedendo siano le caratteristiche prestazionali dell'una rispetto all'altra?
jcolebrand

Risposte:


13

diviso collegato ad alcune informazioni che spiegano il problema di base (ci sono differenze di prestazioni), ma non è abbastanza semplice dire che uno è sempre migliore dell'altro. (altrimenti, non ci sarebbe motivo di avere entrambi.) Inoltre, in MyISM, la dimensione massima di 64k per VARCHAR non è per campo, ma per record.

Fondamentalmente, ci sono 4 modi per archiviare le stringhe nei record del database:

  1. lunghezza fissa
  2. Stringhe di tipo C (contrassegnate con un carattere NULL o simile alla fine della stringa)
  3. Stringhe di stile Pascal (pochi byte per indicare la lunghezza, quindi la stringa)
  4. Puntatori (memorizza la stringa altrove)

MyISM utilizza qualcosa di simile al n. 3 per VARCHAR e un approccio ibrido per TEXT in cui memorizza l'inizio della stringa nel record, quindi il resto della stringa altrove. InnoDB è simile per VARCHAR, ma memorizza il campo TEXT completo al di fuori del record.

Con 1 e 4, le cose nel record hanno sempre la stessa lunghezza, quindi è più facile saltare se non hai bisogno della stringa, ma dopo hai bisogno di cose. Sia il n. 2 che il n. 3 non sono un male per le stringhe brevi ... Il n. 2 deve continuare a cercare l'indicatore, mentre il n. 3 può saltare in avanti ... man mano che le stringhe si allungano, il n. 2 peggiora per questo particolare utilizzo Astuccio.

Se in realtà è necessario leggere la stringa, # 4 è più lento, poiché è necessario leggere il record, quindi leggere la stringa che potrebbe essere memorizzata altrove sul disco, a seconda di come viene gestita dal database. Il n. 1 è sempre piuttosto semplice, e di nuovo ti imbatti in problemi simili in cui per il n. 2 peggiora quanto più lunga è la stringa, mentre il n. 3 è un po 'peggio del n. 2 per stringhe molto piccole, ma migliore man mano che allunga.

Quindi ci sono requisiti di archiviazione ... # 1 è sempre una lunghezza fissa, quindi potrebbe avere un gonfiore se la maggior parte delle stringhe non è la lunghezza massima. # 2 ha 1 byte extra; # 3 in genere ha 2 byte extra se lunghezza massima = 255, 4 byte extra se un massimo di 64k. # 4 ha la lunghezza del puntatore, più le regole per # 3 in genere.

Per le implementazioni specifiche in MySQL 5.1, i documenti per MyISM indicano :

  • Supporto per un vero tipo VARCHAR; una colonna VARCHAR inizia con una lunghezza memorizzata in uno o due byte.
  • Le tabelle con colonne VARCHAR possono avere una lunghezza di riga fissa o dinamica.
  • La somma delle lunghezze delle colonne VARCHAR e CHAR in una tabella può arrivare a 64 KB.

Mentre per InnoDB :

  • La parte a lunghezza variabile dell'intestazione del record contiene un vettore di bit per indicare le colonne NULL. Se il numero di colonne nell'indice che può essere NULL è N, il vettore di bit occupa byte SOFFITTO (N / 8). (Ad esempio, se ci sono da 9 a 15 colonne che possono essere NULL, il vettore di bit utilizza due byte. Le colonne NULL non occupano spazio diverso dal bit in questo vettore. La parte a lunghezza variabile dell'intestazione contiene anche le lunghezze delle colonne a lunghezza variabile. Ogni lunghezza richiede uno o due byte, a seconda della lunghezza massima della colonna. Se tutte le colonne dell'indice NON sono NULL e hanno una lunghezza fissa, l'intestazione del record non ha una parte a lunghezza variabile.
  • Per ogni campo di lunghezza variabile non NULL, l'intestazione del record contiene la lunghezza della colonna in uno o due byte. Saranno necessari due byte solo se parte della colonna viene memorizzata esternamente in pagine di overflow o la lunghezza massima supera 255 byte e la lunghezza effettiva supera 127 byte. Per una colonna memorizzata esternamente, la lunghezza di due byte indica la lunghezza della parte memorizzata internamente più il puntatore da 20 byte alla parte memorizzata esternamente. La parte interna è 768 byte, quindi la lunghezza è 768 + 20. Il puntatore a 20 byte memorizza la lunghezza reale della colonna.

...

come per molte altre cose quando si ha a che fare con i database, se non si è sicuri di ciò che è meglio per le proprie esigenze, provare a confrontarlo con dati e utilizzo simili e vedere come si comportano.


Il thread diviso link afferma che MySQL memorizza BLOB e campi di testo inline forums.mysql.com/read.php?24,105964,267596#msg-267596
Michael Mior,

1
Nitpick ... Per tutti gli scopi pratici, non c'è limite di 64 KB su una riga in entrambi i motori. LONGTEXTe ne LONGBLOBsono un esempio. Le stringhe in stile C non vengono utilizzate da MySQL (di cui sono a conoscenza). InnoDB utilizza un approccio "ibrido", ma è più complesso, a seconda della dimensione della riga, del formato di riga, ecc. La memorizzazione di stringhe in lunghezza "fissa" non è quasi mai consigliabile, tranne quando in realtà sono di lunghezza costante (country_code, zip_code, ecc.) . InnoDB ha 4 ROW_FORMATs; il testo ne discute solo 1 o 2.
Rick James,

2

Quando un SELECT deve creare una tabella temporanea (ad esempio per ordinare i risultati), creerà una tabella MEMORY o una tabella MyISAM. MEMORIA è più efficiente. Ci sono restrizioni sulla MEMORIA - una è di non consentire TEXT e BLOB. Pertanto, un SELECT può funzionare più lentamente con TEXT rispetto a VARCHAR.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.