2009-03-04 13 views
59

Esiste una regola quando è necessario utilizzare i tipi Unicode?Quando è necessario utilizzare NVARCHAR/NCHAR anziché VARCHAR/CHAR in SQL Server?

Ho visto che la maggior parte delle lingue europee (tedesco, italiano, inglese, ...) sono valide nello stesso database nelle colonne VARCHAR.

Sto cercando qualcosa di simile:

  1. Se hai cinese -> uso NVARCHAR
  2. Se si dispone di tedesco e arabo -> uso NVARCHAR

cosa circa il confronto del server/database?

Non voglio usare sempre NVARCHAR come suggerito qui What are the main performance differences between varchar and nvarchar SQL Server data types?

risposta

96

La vera ragione per cui si desidera utilizzare NVARCHAR è quando si hannolingue diverse nella stessa colonna, è necessario indirizzare le colonne in T-SQL senza decodifica, si desidera poter visualizzare i dati "in modo nativo" in SSMS o si desidera standardizzare su Unicode.

Se si considera il database come memoria stupida, è perfettamente possibile memorizzare stringhe estese 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 righe diverse. Significa anche che SQL Server non sarà in grado di gestire facilmente i dati per scopi di interrogazione all'interno di T-SQL su colonne (potenzialmente variabili) codificate.

L'utilizzo di NVARCHAR evita tutto questo.

Vorrei raccomandare NVARCHAR per qualsiasi colonna che contiene dati inseriti dall'utente che sono relativamente non vincolati.

Suggerirei VARCHAR per qualsiasi colonna, che è una chiave naturale (come una targa del veicolo, SSN, il numero di serie, numero di servizio, il numero d'ordine, nominativo aeroporto, ecc) o inserite dall'utente, ma molto vincolata (come un numero di telefono) o un codice (ATTIVO/CHIUSO, S/N, M/F, M/S/D/O, ecc.).Non c'è assolutamente alcun motivo per usare NVARCHAR per quelli.

Così, per una semplice regola:

VARCHAR quando garantito per essere vincolata NVARCHAR altrimenti

+2

>> quando ci sono lingue diverse nella stessa colonna ... Questo è tutto! –

+3

Va notato che * "lingue diverse" * non significa semplicemente che righe diverse possono contenere valori di lingue diverse. Significa anche che le regole di confronto predefinite del database (ad esempio la locale della macchina server) sono diverse dalle impostazioni locali di qualsiasi computer client. per esempio. Il computer server è impostato su 'en-US', ma il mio PC è impostato su' fr-US'. –

+0

@IanBoyd In generale, le regole di confronto saranno molto problematiche quando si mescolano le lingue in una colonna e si ritornano gli elementi in più lingue in un singolo set e si utilizzano le regole di confronto per l'ordine. Le regole di confronto possono anche avere un effetto sui caratteri combinati da trattare come uno (ungherese dz e ly): http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx http://stackoverflow.com/questions/7207590/sql-server-caso-fascicolazione-problema - nvarchar non risolverà questo –

3

greco avrebbe bisogno UTF-8 su N tipi di colonna: αβγ;)

10

Si dovrebbe usare NVARCHAR ogni volta che si hanno a memorizzare più le lingue. Credo che tu debba usarlo per le lingue asiatiche ma non citarlo su di esso.

Ecco il problema se si prende il russo ad esempio e lo si memorizza in un varchar, si andrà bene fintanto che si definisce 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 stesse utilizzando NVARCHAR(), sarebbero gestiti correttamente.

Modifica

Ok vorrei citare MSDN e probabilmente qualche camera ero a specifici ma non voglio per memorizzare la pagina più di un codice in una colonna varcar, mentre è possibile che non dovrebbe

quando avete a che fare con dati di testo che viene immagazzinate nella char, varchar, varchar (max), o il tipo di dati di testo, il più importante limitazione considerare è che solo le informazioni da una singola pagina di codice possono essere convalidate dal loSistema. (È possibile memorizzare i dati da più code page, ma questo non è consigliato.) La tabella codici esatta utilizzata per convalidare e archiviare i dati dipende da sulle regole di confronto della colonna. Se le regole di confronto a livello di colonna non sono state definite , vengono utilizzate le regole di confronto del database . Per determinare il codice della pagina che viene utilizzato per una determinata colonna, è possibile utilizzare la funzione COLLATIONPROPERTY , come mostrato nelle seguenti esempi di codice:

Ecco qualche altro:

Questo esempio illustra il fatto che molte località, come il georgiano e l'hindi , non dispongono di pagine di codice, poiché sono le regole di confronto solo Unicode.Quei regole di confronto non sono appropriati per colonne che utilizzano il char, varchar, o il tipo di dati testo

Così georgiano o Hindi davvero bisogno di essere conservati come nvarchar. L'arabo è anche un problema:

Un altro problema che potreste incontrare è l'incapacità di memorizzare i dati quando non tutti i caratteri che si desidera supporto sono contenute nel codice pagina. In molti casi, Windows considera una tabella codici specifica come una "miglior tabella adatta", che significa che c'è non è possibile garantire che sia possibile fare affidamento sulla tabella codici per gestire tutto il testo; è semplicemente il migliore disponibile. Un esempio di questo è l'alfabeto arabo: supporta una vasta gamma di lingue, tra cui Baluchi, Berbero, Farsi, Kashmiri, kazako, kirghisi, Pashto, Sindhi, Uighur, Urdu, e altro ancora. Tutti nelle lingue abbiamo ulteriori personaggi oltre a quelle nella lingua araba come definito nel codice di Windows pagina 1256. Se si tenta di memorizzare questi caratteri supplementari in una colonna non Unicode che ha la collazione araba , i personaggi sono convertiti in punti interrogativi.

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 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 la cui Y non era simile all'inglese Y. Poi c'è il ch spagnolo che gli utenti spagnoli espongono per essere ordinati dopo h.

Tutto sommato con tutti i problemi che devi affrontare quando si tratta di internalizzazione. È mia opinione che sia più facile usare i caratteri Unicode fin dall'inizio, evitare le conversioni extra e prendere il colpo di spazio. Quindi la mia affermazione in precedenza.

+3

>> È necessario utilizzare NVARCHAR ogni volta che si devono memorizzare più lingue Questo non è vero. Tedesco, italiano e inglese si adattano bene alla stessa tabella con le colonne VARCHAR. Si prega di essere più specifici –

+0

Vedere http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx e http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue per esempi con dz e ly in ungherese. –

2

Josh dice: " .... Qualcosa da tenere a mente quando si utilizza Unicode, anche se è possibile memorizzare lingue diverse in una singola colonna è possibile ordinare solo con una singola fascicolazione. Ci sono alcune lingue che usano caratteri latini ma non ordinano come le altre lingue latine. Accents è un buon esempio di questo, non riesco a ricordare l'esempio ma c'era una lingua dell'est europeo la cui Y non ha sortito l'inglese Y. Poi c'è il ch spagnolo che gli utenti spagnoli espongono per essere ordinati dopo h. "

Sono uno spagnolo madrelingua e "ch" non è una lettera, ma due "c" e "h" e l'alfabeto spagnolo è simile: ABCDEFGHIJKLMN ñ opqrstuvwxyz Non ci aspettiamo "ch" dopo " h "but" i " L'alfabeto è lo stesso che in inglese ad eccezione di ñ o HTML" & ntilde; "

Alex

+0

Ciao Alex, hai mai memorizzato lingue diverse in 1 colonna? Abbiamo avuto colonne diverse per lingue diverse in 1 tabella. –

+0

Probabilmente stanno facendo riferimento al ceco. Abbiamo "ch" tra "h" e "i" ed è una lettera dell'alfabeto separata. – jahav

0

TL; DR;
Unicode - (nchar, nvarchar e ntext)
Non Unicode - (char, varchar e testo).

From MSDN

regole di confronto in SQL Server forniscono regole di ordinamento, caso, e l'accento proprietà di sensibilità per i vostri dati. Le regole di confronto utilizzate con i tipi di dati di carattere come char e varchar dettano la tabella codici e i caratteri corrispondenti che possono essere rappresentati per quel tipo di dati .

Supponendo che si sta utilizzando di default regole di confronto SQL SQL_Latin1_General_CP1_CI_AS poi seguente script dovrebbe stampare tutti i simboli che si può andare bene in VARCHAR in quanto utilizza un byte per memorizzare un carattere (256 in totale), se non si vede su l'elenco stampato - è necessario 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 si modificano le regole di confronto a dire lascia giapponese si noterà che tutte le lettere europee strane trasformate in normale e alcuni simboli in ? marchi.

Unicode è uno standard per la mappatura dei punti di codice ai caratteri. Perché è progettato per coprire tutti i caratteri di tutte le lingue del mondo , non è necessario per diverse code page per gestire diversi set di caratteri . Se si memorizzano i dati dei caratteri che riflettono più lingue , utilizzare sempre i tipi di dati Unicode (nchar, nvarchar e ntext) invece dei tipi di dati non Unicode (char, varchar e text).

In caso contrario, l'ordinamento diventerà strano.

Problemi correlati