2009-03-04 25 views
59

¿Existe una regla cuando debemos usar los tipos Unicode?¿Cuándo debemos usar NVARCHAR/NCHAR en lugar de VARCHAR/CHAR en SQL Server?

He visto que la mayoría de los idiomas europeos (alemán, italiano, inglés, ...) están bien en la misma base de datos en las columnas de VARCHAR.

Busco algo como:

  1. Si tiene chino -> utilización NVARCHAR
  2. Si usted tiene alemán y árabe -> utilización NVARCHAR

¿Qué pasa con la colación del servidor/base de datos?

no quiero utilizar siempre NVARCHAR como sugiere aquí What are the main performance differences between varchar and nvarchar SQL Server data types?

Respuesta

96

El verdadero motivo por el que desea usar NVARCHAR es cuando tiene diferentes idiomas de en la misma columna, necesita direccionar las columnas en T-SQL sin decodificar, desea poder ver los datos "de forma nativa" en SSMS, o si desea estandarizar en Unicode.

Si trata la base de datos como un almacenamiento tonto, es perfectamente posible almacenar cadenas anchas y diferentes codificaciones (incluso de longitud variable) en VARCHAR (por ejemplo, UTF-8). El problema surge cuando intenta codificar y decodificar, especialmente si la página de códigos es diferente para filas diferentes. También significa que SQL Server no podrá tratar los datos fácilmente con el fin de realizar consultas dentro de T-SQL en columnas codificadas (potencialmente variables).

El uso de NVARCHAR evita todo esto.

Recomendaría NVARCHAR para cualquier columna que tenga datos ingresados ​​por el usuario que sean relativamente sin restricciones.

Recomendaría VARCHAR para cualquier columna que sea una clave natural (como la matrícula de un vehículo, SSN, número de serie, etiqueta de servicio, número de pedido, indicativo del aeropuerto, etc.) o ingresada por el usuario, pero muy restringida (como número de teléfono) o un código (ACTIVO/CERRADO, S/N, M/F, M/S/D/W, etc.).No hay absolutamente ninguna razón para usar NVARCHAR para eso.

Así que para una simple regla:

VARCHAR cuando se garantiza que sea constreñido NVARCHAR lo contrario

+2

>> cuando tiene idiomas diferentes en la misma columna ... ¡Eso es todo! –

+3

Debe tenerse en cuenta que * "idiomas diferentes" * no solo significa que diferentes filas pueden contener valores de diferentes idiomas. También significa si la intercalación predeterminada de la base de datos (es decir, la configuración regional de la máquina servidor) es diferente de la configuración regional de cualquier computadora cliente. p.ej. La máquina del servidor está configurada en 'en-US', pero mi PC está configurada en' fr-US'. –

+0

@IanBoyd En general, la intercalación será muy problemática al mezclar idiomas en una columna y devolver elementos en múltiples idiomas en un solo conjunto y usar esa intercalación para ordenar. La intercalación también puede tener un efecto sobre los caracteres que se combinan para tratarse como uno (húngaro dz y ly): http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue - nvarchar no va a resolver eso –

3

griega necesitaría UTF-8 en la N tipos de columna: αβγ;)

10

Debe utilizar NVARCHAR en cualquier momento usted tiene que almacenar múltiples idiomas. Creo que debes usarlo para los idiomas asiáticos, pero no me cites.

Este es el problema si toma el ruso por ejemplo y lo almacena en varchar, estará bien mientras defina la página de códigos correcta. Pero supongamos que usa una instalación sql en inglés predeterminada, y los caracteres rusos no se manejarán correctamente. Si usabas NVARCHAR(), se manejarían correctamente.

Editar

Ok permítanme citar MSDN y maybee debía específica pero no quiero almacenar más de una página de código en una columna varcar, mientras que se puede que no debería

Cuando tratas con datos de texto que se almacena en el char, varchar, varchar (max) o tipo de datos de texto, el limitación más importante a considerar es que sólo la información desde una única página de códigos puede ser validada por el sistema. (Puede almacenar datos desde páginas de códigos múltiples, pero esto no es recomendado.) La página de códigos exacta utilizada para validar y almacenar los datos depende en la intercalación de la columna. Si se ha definido una intercalación de nivel de columna no se ha definido , se utiliza la intercalación de la base de datos . Para determinar la página de códigos que se utiliza para una columna determinada, puede utilizar la función COLLATIONPROPERTY , como se muestra en los siguientes ejemplos de código:

Aquí hay más:

Este ejemplo ilustra el hecho de que muchas configuraciones regionales, como Georgian y Hindi, no tienen páginas de códigos, ya que son intercalaciones Unicode-only.Esos colaciones no son apropiados para columnas que utilizan el carbón, varchar o tipo de datos de texto

Así Georgia o hindi realmente necesitan ser almacenados como nvarchar. El árabe es también un problema:

Otro problema que se puede encontrar es la incapacidad para almacenar datos cuando no todos los caracteres que desea apoyo están contenidos en el código de la página . En muchos casos, Windows considera que una página de códigos particular es una "mejor página de códigos ", lo que significa que hay sin garantía de que puede confiar en la página de códigos para manejar todo el texto; es simplemente el mejor disponible. Un ejemplo de esto es la escritura árabe: es compatible con una amplia variedad de idiomas, incluyendo Baluchi, Berber, persa, de Cachemira, kazajo, kirguís, pashto, sindhi, uigur, urdu, y mucho más. Todas idiomas tienen caracteres adicionales más allá de los de la lengua árabe como se define en la página de códigos de Windows 1256. Si se intenta almacenar estos caracteres adicionales en una columna no Unicode que tiene la colación árabe , los caracteres son convertidos en signos de interrogación.

Algo que se debe tener en cuenta cuando se utiliza Unicode aunque se pueden almacenar diferentes idiomas en una sola columna, solo se puede ordenar usando una única intercalación. Hay algunos idiomas que usan caracteres latinos pero no los clasifican como otros idiomas latinos. Acentos es un buen ejemplo de esto, no puedo recordar el ejemplo, pero había un idioma de Europa del Este cuya Y no se ordenó como la Y española. Luego está el español ch que los usuarios españoles esperan clasificar después de h.

En definitiva, con todos los problemas que tiene que tratar cuando se trata de internalitionalization. En mi opinión, es más fácil usar los caracteres Unicode desde el principio, evitar las conversiones adicionales y aprovechar el éxito del espacio. De ahí mi declaración anterior.

+3

>> Debe usar NVARCHAR cada vez que tenga que almacenar varios idiomas Esto no es cierto. El alemán, el italiano y el inglés encajan bien en la misma tabla con las columnas VARCHAR. Sea más específico –

+0

Vea http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx y http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue para ver ejemplos con dz y ly en húngaro. –

2

Josh dice: " .... Algo a tener en cuenta cuando se utiliza Unicode aunque se puede almacenar diferentes idiomas en una sola columna, solo se puede ordenar usando una sola intercalación. Hay algunos idiomas que usan caracteres latinos pero no se ordenan como otros idiomas latinos. Acentos es un buen ejemplo de esto, no puedo recordar el ejemplo, pero sí un idioma de Europa del Este cuya Y no se clasificó como la Y española. Luego está el español ch, que los usuarios españoles esperan que se clasifique después de h ".

Soy un hablante nativo de español y "ch" no es una carta, sino dos "c" y "h" y el alfabeto español es como: abcdefghijklmn N OPQRSTUVWXYZ No esperamos que la "ch" después " h "pero" i " El alfabeto es el mismo que en inglés, excepto el ñ o en HTML" & ntilde; "

Alex

+0

Hola Alex, ¿alguna vez almacenaste diferentes idiomas en 1 columna? Tuvimos diferentes columnas para diferentes idiomas en 1 tabla. –

+0

Probablemente están haciendo referencia a checo. Tenemos "ch" entre "h" e "i" y es una letra del alfabeto por separado. – jahav

0

TL; DR;
Unicode - (nchar, nvarchar y ntext)
No unicode - (char, varchar y texto).

From MSDN

colaciones en SQL Server proporcionan reglas de clasificación, el caso, y el acento propiedades de sensibilidad para sus datos. Las intercalaciones que se utilizan con los tipos de datos de caracteres , como char y varchar, dictan la página de códigos y los caracteres correspondientes que se pueden representar para ese tipo de datos .

Suponiendo que está utilizando SQL intercalación predeterminada SQL_Latin1_General_CP1_CI_AS siguiente script a continuación, debe imprimir todos los símbolos que puede caber en VARCHAR ya que utiliza un byte para almacenar un carácter (256 en total) si no lo ve en la lista impresa: necesita 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 

Si cambia el cotejo a que permite decir japonés se dará cuenta de que todas las letras europeas extraños se convirtió en normal y algunos símbolos en ? marcas.

Unicode es un estándar para asignar puntos de código a los caracteres. Porque está diseñado para cubrir todos los caracteres de todos los idiomas del mundo , no hay necesidad de diferentes páginas de códigos para manejar diferentes conjuntos de caracteres . Si almacena datos de caracteres que reflejan varios idiomas , siempre utilice los tipos de datos Unicode (nchar, nvarchar y ntext) en lugar de los tipos de datos que no son Unicode (char, varchar y text).

De lo contrario, su clasificación será rara.

Cuestiones relacionadas