Quando dobbiamo usare NVARCHAR / NCHAR invece di VARCHAR / CHAR in SQL Server?
-
03-07-2019 - |
Domanda
Esiste una regola quando dobbiamo usare i tipi Unicode?
Ho visto che la maggior parte delle lingue europee (tedesco, italiano, inglese, ...) stanno bene nello stesso database nelle colonne VARCHAR.
Sto cercando qualcosa del tipo:
- Se hai cinese - > usa NVARCHAR
- Se hai tedesco e arabo - > usa NVARCHAR
Che dire delle regole di confronto del server / database?
Non voglio usare sempre NVARCHAR come suggerito qui Quali sono le principali differenze di prestazioni tra i tipi di dati varchar e nvarchar SQL Server?
Soluzione
Il vero motivo per cui vuoi utilizzare NVARCHAR è quando hai lingue diverse nella stessa colonna, devi indirizzare le colonne in T-SQL senza decodifica, vuoi essere in grado di vedere il dati "nativamente" in SSMS o desideri standardizzare su Unicode.
Se si considera il database come memoria stupida, è perfettamente possibile archiviare stringhe ampie e codifiche diverse (anche di lunghezza variabile) in VARCHAR (ad esempio UTF-8). Il problema si presenta quando si tenta di codificare e decodificare, soprattutto se la tabella codici è diversa per le diverse righe. Significa anche che SQL Server non sarà in grado di gestire facilmente i dati per scopi di query all'interno di T-SQL su colonne codificate (potenzialmente variabili).
L'uso di NVARCHAR evita tutto questo.
Vorrei raccomandare NVARCHAR per qualsiasi colonna che contenga dati inseriti dall'utente relativamente non vincolati.
Consiglierei VARCHAR per qualsiasi colonna che è una chiave naturale (come una targa del veicolo, SSN, numero di serie, etichetta di servizio, numero d'ordine, nominativo dell'aeroporto, ecc.) che è generalmente definita e vincolata da uno standard o da una legislazione o convenzione. Anche VARCHAR per l'utente inserito e molto vincolato (come un numero di telefono) o un codice (ATTIVO / CHIUSO, S / N, M / F, M / S / D / W, ecc.). Non c'è assolutamente alcun motivo per usare NVARCHAR per quelli.
Quindi per una semplice regola:
VARCHAR quando garantito di essere vincolato NVARCHAR altrimenti
Altri suggerimenti
Dovresti usare NVARCHAR ogni volta che devi memorizzare più lingue. Credo che tu debba usarlo per le lingue asiatiche ma non citarmi su di esso.
Ecco il problema se prendi ad esempio il russo e lo memorizzi in un varchar, starai bene finché definirai la tabella codici corretta. Ma supponiamo che tu stia utilizzando un'installazione sql inglese predefinita, quindi i caratteri russi non verranno gestiti correttamente. Se si utilizza NVARCHAR (), verranno gestiti correttamente.
Modifica
Ok, lasciami citare MSDN e forse sono stato a specifico ma non si desidera memorizzare più di una tabella codici in una colonna varcar, mentre è possibile non si dovrebbe
Quando hai a che fare con i dati di testo memorizzato nel carattere, varchar, varchar (max), o tipo di dati di testo, il limitazione più importante da considerare è che solo informazioni da un singolo la tabella codici può essere convalidata dal sistema. (È possibile memorizzare i dati da più pagine di codice, ma non lo è consigliato.) La tabella codici esatta utilizzata per convalidare e archiviare i dati dipende sulla raccolta della colonna. Se una le regole di confronto a livello di colonna non sono state definito, le regole di confronto del database viene usato. Per determinare la tabella codici che viene utilizzato per una determinata colonna, tu può usare la COLLATIONPROPERTY funzione, come mostrato di seguito esempi di codice:
Eccone qualche altro:
Questo esempio illustra il fatto che molti locali, come georgiano e Hindi, non hanno le code page, come loro sono regole di confronto solo Unicode. quelli le regole di confronto non sono appropriate per colonne che utilizzano char, varchar o tipo di dati di testo
Quindi il georgiano o l'hindi devono davvero essere archiviati come nvarchar. Anche l'arabo è un problema:
Un altro problema che potresti incontrare è l'impossibilità di conservare i dati quando non lo sono tutti i personaggi che desideri il supporto è contenuto nel codice pagina. In molti casi, Windows considera una determinata tabella codici è la migliore montare " code page, il che significa che c'è nessuna garanzia che si possa fare affidamento su code page per gestire tutto il testo; è semplicemente il migliore disponibile. Un esempio di questo è la scrittura araba: supporta una vasta gamma di lingue, tra cui Baluchi, Berber, Farsi, Kashmir, Kazako, Kirghiz, Pashto, Sindhi, Uighur, Urdu e altro. Tutto di queste lingue hanno ulteriori personaggi oltre quelli in arabo lingua come definita nel codice di Windows pagina 1256. Se si tenta di memorizzare questi personaggi extra in a colonna non Unicode che ha l'arabo collazione, i personaggi sono convertito in punti interrogativi.
Qualcosa da tenere a mente quando si utilizza Unicode sebbene sia possibile memorizzare lingue diverse in una singola colonna, è possibile ordinare solo utilizzando una singola fascicolazione. Ci sono alcune lingue che usano caratteri latini ma non si ordinano come le altre lingue latine. Gli accenti ne sono un buon esempio, non riesco a ricordare l'esempio ma c'era una lingua dell'Europa orientale il cui Y non era in ordine come l'inglese Y. Poi c'è il ch spagnolo che gli utenti spagnoli si aspettano di essere ordinati dopo h.
Tutto sommato con tutti i problemi che devi affrontare quando si tratta di internalizzazione. È mia opinione che sia più semplice utilizzare i caratteri Unicode dall'inizio, evitare le conversioni extra e ottenere lo spazio. Da qui la mia affermazione in precedenza.
Il greco avrebbe bisogno di UTF-8 su tipi di colonna N: aß?;)
Josh dice: " .... Qualcosa da tenere a mente quando si utilizza Unicode anche se è possibile memorizzare lingue diverse in una singola colonna, è possibile ordinare solo utilizzando una singola fascicolazione. Ci sono alcune lingue che usano caratteri latini ma non si ordinano come le altre lingue latine. Gli accenti sono un buon esempio di questo, non posso ricordare l'esempio ma c'era una lingua dell'Europa orientale il cui Y non era in ordine come l'inglese Y. Poi c'è il ch spagnolo che gli utenti spagnoli si aspettano di essere ordinati dopo h. & Quot ;
Sono un madrelingua spagnolo e " ch " non è una lettera ma due "c" e " h " e l'alfabeto spagnolo è come: abcdefghijklmn & # 241; opqrstuvwxyz Non ci aspettiamo che " ch " dopo " h " ma " i " L'alfabeto è lo stesso dell'inglese ad eccezione di & # 241; o in HTML " & amp; ntilde; "
Alex
TL; DR;
Unicode - (nchar, nvarchar e ntext)
Non unicode - (char, varchar e text).
Le regole di confronto in SQL Server forniscono regole di ordinamento, caso e accento proprietà di sensibilità per i tuoi dati. Collazioni che vengono utilizzate con tipi di dati carattere come char e varchar dettano la tabella codici e i caratteri corrispondenti che possono essere rappresentati per tali dati tipo.
Supponendo che si stiano utilizzando le regole di confronto SQL predefinite SQL_Latin1_General_CP1_CI_AS
, lo script seguente dovrebbe stampare tutti i simboli che è possibile inserire in VARCHAR
poiché utilizza un byte per memorizzare un carattere ( 256 in totale) se non lo vedi nell'elenco stampato, devi NVARCHAR
.
declare @i int = 0;
while (@i < 256)
begin
print cast(@i as varchar(3)) + ' '+ char(@i) collate SQL_Latin1_General_CP1_CI_AS
print cast(@i as varchar(3)) + ' '+ char(@i) collate Japanese_90_CI_AS
set @i = @i+1;
end
Se cambi la collazione per dire giapponese, noterai che tutte le strane lettere europee sono diventate normali e alcuni simboli in ?
.
Unicode è uno standard per mappare i punti di codice sui caratteri. Perché è progettato per coprire tutti i personaggi di tutte le lingue di mondo, non è necessario che diverse code page gestiscano differenti set di caratteri. Se memorizzi i dati dei personaggi che riflettono più lingue, usa sempre i tipi di dati Unicode (nchar, nvarchar e ntext) anziché i tipi di dati non Unicode (char, varchar e text).
Altrimenti il ??tuo ordinamento diventerà strano.