Qual è la differenza tra char, nchar, varchar e nvarchar in SQL Server?


625

Cosa si intende con nvarchar ?

Qual è la differenza tra char, nchar, varchar, e nvarcharin SQL Server?

Risposte:


859

Solo per chiarire ... o riassumere ...

  • nchare nvarcharpuò memorizzare caratteri Unicode .
  • chare non può memorizzare caratteri Unicode .varchar
  • chare ncharsono a lunghezza fissa che riservano spazio di archiviazione per il numero di caratteri specificati anche se non si utilizza tutto quello spazio.
  • varchare nvarcharsono di lunghezza variabile che utilizzerà solo gli spazi per i personaggi che memorizzi. Non riserverà l'archiviazione come charonchar .

nchare nvarcharoccuperà il doppio dello spazio di archiviazione, quindi potrebbe essere saggio usarli solo se è necessario il supporto Unicode .


15
char e varchar non sono pensati per memorizzare unicode, ma con alcuni trucchi di codifica aggiuntivi e logica aggiuntiva, è ancora possibile utilizzare in modo improprio un campo [var] char per l'archiviazione unicode.
Wim ten Brink,

10
Dipende dal confronto se le n...versioni occupano o meno il doppio dello spazio di archiviazione rispetto alla mia risposta
Martin Smith,

7
Qual è il vantaggio di prenotare l'archiviazione?
mlissner,

4
Sull'ultimo punto: l'utilizzo di Unicode nchar e nvarchar è ancora migliore nella maggior parte dei casi, migliore confronto, flessibilità per gli utenti, elimina i futuri problemi di compatibilità. E a proposito, lo spazio di archiviazione non è un problema per questo caso, poiché l'utilizzo delle regole di confronto senza Unicode è molto problematico e le velocità di memoria continueranno a diminuire in futuro
Jaison Varghese,

6
@BenCaine char (20) utilizzerà 20 byte (presupponendo un confronto a 8 bit); varchar (20) utilizzerà len (dati) +2 byte, ovvero 22 per 20 byte di dati, ma solo 12 per 10 byte di dati. I due byte extra sono i record di lunghezza. Se i tuoi dati saranno sempre a tutta lunghezza, utilizza un carattere, in quanto consente di risparmiare spazio e potrebbe essere più veloce. Per favore, non usare mai un varchar (1) o qualcosa di più piccolo di un varchar (4). Un singolo carattere in formato varchar utilizza tre byte, quindi un char (3) non utilizzerà mai più spazio di un varchar (3).
Richard Gadsden,

95

Tutte le risposte finora indicano che varcharè singolo byte, nvarchar è doppio byte. La prima parte di questo in realtà dipende dalle regole di confronto, come illustrato di seguito.

DECLARE @T TABLE
(
C1 VARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS,
C2 NVARCHAR(20)COLLATE  Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS
)

INSERT INTO @T 
    VALUES (N'中华人民共和国',N'中华人民共和国'),
           (N'abc',N'abc');

SELECT C1,
       C2,
       LEN(C1)        AS [LEN(C1)],
       DATALENGTH(C1) AS [DATALENGTH(C1)],
       LEN(C2)        AS [LEN(C2)],
       DATALENGTH(C2) AS [DATALENGTH(C2)]
FROM   @T  

ritorna

inserisci qui la descrizione dell'immagine

Nota che i caratteri e non erano ancora rappresentati nella VARCHARversione e sono stati silenziosamente sostituiti con ?.

In realtà non ci sono ancora caratteri cinesi che possono essere rappresentati da un singolo byte in quel confronto. Gli unici caratteri a byte singolo sono il tipico set ASCII occidentale.

Per questo motivo è possibile che un inserimento da una nvarchar(X)colonna a una varchar(X)colonna fallisca con un errore di troncamento (dove X indica un numero uguale in entrambi i casi).

SQL Server 2012 aggiunge regole di confronto SC (carattere supplementare) che supportano UTF-16. In queste regole di confronto un singolo nvarcharcarattere può richiedere 2 o 4 byte.


4
Il tipo di risposta che stavo cercando. Anche per risparmiare tempo come me - il testo non inglese si traduce in "Repubblica popolare cinese" translate.google.com/#auto/it/…
Igand

34

nchar e char funzionano praticamente nello stesso modo l'uno dell'altro, così come nvarchar e varchar. L'unica differenza tra loro è che nchar / nvarchar memorizza i caratteri Unicode (essenziali se si richiede l'uso di set di caratteri estesi) mentre varchar no.

Poiché i caratteri Unicode richiedono più spazio di archiviazione, i campi nchar / nvarchar occupano il doppio dello spazio (quindi ad esempio nelle versioni precedenti di SQL Server la dimensione massima di un campo nvarchar è 4000).

Questa domanda è una copia di questa .


3
Dimentichi una cosa: nchar usa una lunghezza fissa, quindi nchar (10) deve sempre ricevere dieci caratteri. E varchar (10) è davvero Unicode e accetterà qualsiasi numero di caratteri, fino a 10 caratteri. Vedi anche msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink

33

Solo per aggiungere qualcosa in più: nchar - aggiunge spazi finali ai dati. nvarchar : non aggiunge spazi finali ai dati.

Pertanto, se si intende filtrare il set di dati in base a un campo 'nchar', è possibile utilizzare RTRIM per rimuovere gli spazi. Ad esempio, il campo nchar (10) chiamato BRAND memorizza la parola NIKE. Aggiunge 6 spazi a destra della parola. Quindi, durante il filtraggio, l'espressione dovrebbe essere: RTRIM (Fields! BRAND.Value) = "NIKE"

Spero che questo aiuti qualcuno là fuori perché stavo lottando con esso per un po 'proprio ora!


24

Il mio tentativo di riassumere e correggere le risposte esistenti:

Innanzitutto, chare ncharutilizzerà sempre una quantità fissa di spazio di archiviazione, anche quando la stringa da archiviare è più piccola dello spazio disponibile, mentre varchare nvarcharutilizzerà solo lo spazio di archiviazione necessario per archiviare quella stringa (più due byte di overhead, presumibilmente per memorizzare la lunghezza della stringa). Quindi ricorda, "var" significa "variabile", come nello spazio variabile.

Il secondo punto importante da capire è quello, nchare nvarcharmemorizzare le stringhe usando esattamente due byte per carattere, mentre chare varcharusare una codifica determinata dalla tabella codici di confronto, che di solito sarà esattamente un byte per carattere (anche se ci sono eccezioni, vedi sotto). Usando due byte per carattere, è possibile memorizzare una vasta gamma di caratteri, quindi la cosa fondamentale da ricordare qui è quella nchare nvarchartendono ad essere una scelta molto migliore quando si desidera il supporto per l'internazionalizzazione, cosa che probabilmente si fa.

Ora per alcuni punti più fini.

In primo luogo, nchare nvarcharle colonne sempre memorizzare i dati usando UCS-2. Ciò significa che verranno utilizzati esattamente due byte per carattere e qualsiasi carattere Unicode nel piano multilingue di base (BMP) può essere memorizzato da un campo ncharo nvarchar. Tuttavia, non è possibile memorizzare alcun carattere Unicode. Ad esempio, secondo Wikipedia, i punti di codice per i geroglifici egiziani non rientrano nel BMP. Vi sono, quindi, stringhe Unicode che possono essere rappresentate in UTF-8 e altre codifiche Unicode vere che non possono essere archiviate in un server ncharo nvarcharcampo SQL , e le stringhe scritte in geroglifici egiziani sarebbero tra queste. Fortunatamente i tuoi utenti probabilmente non scrivono in quello script, ma è qualcosa da tenere a mente!

Un'altra fonte di confusione ma il punto interessante che altri utenti hanno messo in evidenza è che chare varcharcampi possono utilizzare due byte per carattere per certi personaggi se la pagina collazione di codici richiede. (Martin Smith fornisce un eccellente esempio in cui mostra come Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS mostra questo comportamento. Dai un'occhiata.)

AGGIORNAMENTO: A partire da SQL Server 2012, ci sono finalmente le code page per UTF-16 , ad esempio Latin1_General_100_CI_AS_SC, che può davvero coprire l'intero intervallo Unicode.


14
  • char: dati di caratteri a lunghezza fissa con una lunghezza massima di 8000 caratteri.
  • nchar: dati unicode a lunghezza fissa con una lunghezza massima di 4000 caratteri.
  • Char = Lunghezza 8 bit
  • NChar = Lunghezza di 16 bit

charnon poteva avere una lunghezza di 8 bit. Non deve memorizzare la lunghezza e la lunghezza fissa può contenere fino a 8000 caratteri.
John B. Lambe,

12

nchar[(n)] (carattere nazionale)

  • Dati stringa Unicode a lunghezza fissa .
  • n definisce la lunghezza della stringa e deve essere un valore compreso tra 1 e 4.000.
  • La dimensione di archiviazione è due volte nbyte.

nvarchar [(n | max)] (carattere nazionale variabile).

  • Dati stringa Unicode a lunghezza variabile .
  • n definisce la lunghezza della stringa e può essere un valore compreso tra 1 e 4.000.
  • max indica che la dimensione massima di archiviazione è 2 ^ 31-1 byte (2 GB).
  • La dimensione della memoria, in byte, è due volte la lunghezza effettiva dei dati immessi + 2 byte

char [(n)] (carattere)

  • non-UnicodeDati di stringa a lunghezza fissa .
  • n definisce la lunghezza della stringa e deve essere un valore compreso tra 1 e 8.000.
  • La dimensione della memoria è di nbyte.

varchar [(n | max)] (carattere variabile)

  • Dati stringa di lunghezza variabile, non Unicode .
  • n definisce la lunghezza della stringa e può essere un valore compreso tra 1 e 8.000.
  • max indica che la dimensione massima di archiviazione è 2 ^ 31-1 byte (2 GB).
  • La dimensione di archiviazione è la lunghezza effettiva dei dati immessi + 2 byte.

7

Le differenze sono:

  1. n [var] char memorizza unicode mentre [var] char memorizza solo caratteri a byte singolo.
  2. [n] char richiede un numero fisso di caratteri della lunghezza esatta mentre [n] varchar accetta un numero variabile di caratteri fino alla lunghezza definita inclusa.

Un'altra differenza è la lunghezza. Sia nchar che nvarchar possono avere una lunghezza massima di 4.000 caratteri. E char e varchar possono contenere fino a 8000 caratteri. Ma per SQL Server puoi anche usare un [n] varchar (max) che può gestire fino a 2.147.483.648 caratteri. (Due gigabyte, un intero con segno a 4 byte.)


7

nchar richiede più spazio di nvarchar.

per esempio,

Un nchar (100) memorizzerà sempre 100 caratteri anche se inserisci solo 5, i restanti 95 caratteri saranno riempiti di spazi. La memorizzazione di 5 caratteri in un nvarchar (100) salverà 5 caratteri.


6
Non del tutto vero, poiché è necessario riempire un carattere (100) con un massimo di 100 caratteri. Lo useresti quando, ad esempio, memorizzi i numeri di telefono nel tuo database o ordini numeri di lunghezza fissa. Poiché la lunghezza del campo è fissa, non è possibile scegliere di riempire fino al numero massimo di caratteri. Ma quando tutti i tuoi dati sono di 100 caratteri per record, un carattere (100) occuperà meno spazio di un varchar (100) perché non ha bisogno di un'indicazione di lunghezza: ogni valore sarebbe esattamente di 100 caratteri.
Wim ten Brink,

5

nchar (10) è una stringa Unicode a lunghezza fissa di lunghezza 10. nvarchar (10) è una stringa Unicode a lunghezza variabile con una lunghezza massima di 10. In genere, si utilizza il primo se tutti i valori dei dati sono 10 caratteri e il secondo se le lunghezze variano.


Confronto errato - la domanda riguarda nchar e varchar, non nchar e nvarchar.
Luke Bennett,

4
  • nchar è a lunghezza fissa e può contenere caratteri unicode. utilizza una memoria di due byte per carattere.

  • varchar è di lunghezza variabile e non può contenere caratteri unicode. utilizza una memoria byte per carattere.


Sbagliato. Unicode può usare da 1 a 4 byte (in generale) per ogni carattere. Inoltre, un varchar può contenere unicode, ma non è riconosciuto come unicode. Di conseguenza, un varchar è considerato inaffidabile per l'archiviazione unicode. (Soprattutto perché c'è il rischio che il codice che accede al campo lo traduca in modo errato.)
Wim ten Brink

@Alex: penso che tu abbia espresso il tuo punto di vista, ma non sono ancora d'accordo con te. Quello che stai dicendo è che un int PUO 'contenere un long se il long sembra essere inferiore a 2 ^ 32. Questo non è solo "inaffidabile", è una limitazione intrinseca che rende impossibile coprire l'intero intervallo di valori.
Manu,

4
@Workshop Alex: sbagliato. Unicode codificato come UCS-2(che risulta essere la codifica utilizzata da SQL Server) memorizza ogni carattere esattamente due byte, vedi msdn.microsoft.com/en-us/library/bb330962%28v=sql.90%29.aspx : SQL Server stores Unicode in the UCS-2 encoding scheme... UCS-2 is a fixed-length encoding that represents all characters as a 16-bit value (2 bytes). SQL Server 2008 può utilizzare la compressione SCSU, ma è ancora la compressione delle stringhe Unicode codificate UCS-2: msdn.microsoft.com/en-us/library/ee240835.aspx
Remus Rusanu

2

NVARCHAR può memorizzare caratteri Unicode e richiede 2 byte per carattere.


1
SBAGLIATO! Unicode utilizza tra 1 e 4 byte per carattere! Molte persone lo dimenticano! Anche l'uso di UTF-16 potrebbe comportare che alcuni caratteri assumano 4 byte anziché 2, sebbene la lunghezza comune sia di 2 byte. Alcuni altri formati secondari di Unicode potrebbero richiedere anche più di 4 byte!
Wim ten Brink,

7
@WimtenBrink: la domanda riguarda SQL Server e nvarcharrichiede sempre 2 byte per carattere.
Martin Smith,

@Wim, hai ragione, ci sono diverse codifiche per Unicode che possono produrre un diverso numero di byte. Ma SQL Server non offre una scelta sulla codifica Unicode. SQL Server prima del 2012 utilizzava solo UCS-2, largo due byte, quindi Martin aveva ragione nel momento in cui ha scritto la risposta. Come hanno già detto altre risposte, SQL Server 2012 ora fornisce UTF-16, quindi due byte per molti caratteri (quelli nel piano multilingua Unicode Basic), quattro byte per altri.
Concrete Gannet,
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.