¿Cuándo debemos usar NVARCHAR / NCHAR en lugar de VARCHAR/CHAR en SQL Server?


¿Hay una regla cuando debemos usar los tipos Unicode?

He visto que la mayoría de las lenguas europeas (Alemán, Italiano, Inglés,...) están bien en la misma base de datos en columnas VARCHAR.

Estoy buscando algo como:

  1. Si tienes chino use> usa NVARCHAR
  2. Si tienes alemán y árabe use> usa NVARCHAR

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

No quiero usar siempre NVARCHAR como se sugiere aqui ¿Cuáles son las principales diferencias de rendimiento entre los tipos de datos varchar y nvarchar SQL Server?

Author: Community, 2009-03-05

5 answers

La verdadera razón por la que desea usar NVARCHAR es cuando tiene diferentes lenguajes en la misma columna, necesita direccionar las columnas en T-SQL sin decodificar, desea poder ver los datos "de forma nativa" en SSMS, o desea estandarizar en Unicode.

Si se trata la base de datos como almacenamiento tonto, es perfectamente posible almacenar cadenas anchas y codificaciones diferentes (incluso de longitud variable) en VARCHAR (por ejemplo UTF-8). El problema viene cuando usted está tratando de codificar y decodificar, especialmente si la página de códigos es diferente para diferentes filas. También significa que el servidor SQL no será capaz de tratar con los datos fácilmente para fines de consulta dentro de T-SQL en (potencialmente variable) columnas codificadas.

Usando NVARCHAR evita todo esto.

Recomendaría NVARCHAR para cualquier columna que tenga datos ingresados por el usuario que esté relativamente libre de restricciones.

Recomendaría VARCHAR para cualquier columna que sea una clave natural (como una matrícula del vehículo, SSN, número de serie, etiqueta de servicio, número de pedido, indicativo del aeropuerto, etc.) que normalmente se define y restringe por una norma o legislación o convención. También VARCHAR para el usuario introducido, y muy restringido (como un número de teléfono) o un código (ACTIVO/CERRADO, Y/N, M/F, M/S/D/W, etc). No hay absolutamente ninguna razón para usar NVARCHAR para eso.

Así que para una regla simple:

VARCHAR cuando se garantiza que está restringido NVARCHAR de otro modo

 105
Author: Cade Roux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-16 13:07:50

Debe usar NVARCHAR cada vez que tenga que almacenar varios idiomas. Creo que tiene que usarlo para las lenguas asiáticas, pero no me cite en él.

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

Editar

Ok permítanme citar MSDN y maybee yo era específico, pero usted no quiere almacenar más de una página de código en una columna varcar, mientras que usted puede usted no debe

Cuando se trata de datos de texto que es almacenado en el char, varchar, varchar (max), o tipo de datos de texto, el limitación más importante a considerar es que solo la información de un solo página de código puede ser validado por el sistema. (Puede almacenar datos desde múltiples páginas de código, pero esto no es recomendar.) La página de códigos exacta utilizada para validar y almacenar los datos depende en el cotejo de la columna. Si a no se ha realizado el cotejo a nivel de columna definido, el cotejo de la base de datos se utiliza. Para determinar la página de códigos que se utiliza para una columna dada, usted puede utilizar el COLLATIONPROPERTY función, como se muestra en la siguiente ejemplos de código:

Aquí hay algo más:

Este ejemplo ilustra el hecho de que muchos locales, tales como Georgiano y Hindi, no tienen páginas de código, ya que son solo intercalaciones Unicode. Aquellos las colaciones no son apropiadas para columnas que usan el char, varchar, o tipo de datos de texto

Así que el georgiano o el hindi realmente deben almacenarse como nvarchar. El árabe también es un problema:

Otro problema que puede encontrar es la imposibilidad de almacenar datos cuando no todos los personajes que deseas el soporte está contenido en el código pagina. En muchos casos, Windows considerar una página de código en particular para ser un " mejor ajustar " página de códigos, lo que significa que hay no hay garantía de que usted puede confiar en el página de código para manejar todo el texto; es simplemente el mejor disponible. Un ejemplo de esto es la escritura árabe: es compatible con una amplia gama de idiomas, incluyendo Baluchi, bereber, Farsi, Cachemir, Kazajo, Kirguiz, Pashto, Sindhi, Uighur, Urdu y más. Todos estos idiomas tienen adicional caracteres más allá de los del árabe idioma tal como se define en Código de Windows página 1256. Si intenta almacenar estos personajes extra en un columna no Unicode que tiene el árabe cotejo, los personajes son convertido en signos de interrogación.

Algo a tener en cuenta cuando se utiliza Unicode aunque puede almacenar diferentes idiomas en una sola columna, solo puede ordenar usando una sola intercalación. Hay algunos idiomas que utilizan caracteres latinos, pero no se clasifican como otros idiomas latinos. Acentos es un buen ejemplo de esto, I no puedo recordar el ejemplo, pero había un idioma de Europa del este cuya Y no se clasificó como la Y inglesa. Luego está la ch española que los usuarios españoles expet para ser ordenados después de h.

En general, con todos los problemas que tiene que tratar cuando se trata de internalitionalización. Es mi opinión que es más fácil simplemente usar caracteres Unicode desde el principio, evitar las conversiones adicionales y tomar el espacio golpeado. De ahí mi declaración anterior.

 10
Author: JoshBerke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 02:56:20

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

 3
Author: cherouvim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-04 21:11:23

Josh dice: "....Algo a tener en cuenta cuando se utiliza Unicode aunque puede almacenar diferentes idiomas en una sola columna, solo puede ordenar usando una sola intercalación. Hay algunos idiomas que utilizan caracteres latinos, pero no se 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 ordenar como el inglés Y. Luego está el español ch que los usuarios españoles expet para ser ordenados después h. "

Soy hablante nativo de español y " ch "no es una letra sino dos" c " y " h " y el alfabeto español es como: abcdefghijklmn ñ opqrstuvwxyz No esperamos " ch "después de" h "pero" i" El alfabeto es el mismo que en inglés excepto por la ñ o en HTML "ñ "

Alex

 2
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-04 06:15:30

TL; DR;
Unicode - (nchar, nvarchar, and ntext)
Non-unicode- (char, varchar, and text).

De MSDN

Las intercalaciones en SQL Server proporcionan reglas de ordenación, mayúsculas y minúsculas propiedades de sensibilidad para sus datos. 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 esos datos tipo.

Asumiendo que está utilizando por defecto SQL collation SQL_Latin1_General_CP1_CI_AS a continuación, el siguiente script 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 cambias la intercalación a digamos japonés, notarás que todas las extrañas letras europeas se convirtieron en normales y algunos símbolos en ? marcas.

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

De lo contrario, su clasificación se volverá rara.

 0
Author: Matas Vaitkevicius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-23 15:22:15