¿Cuándo debemos usar NVARCHAR / NCHAR en lugar de VARCHAR / CHAR en SQL Server?
-
03-07-2019 - |
Pregunta
¿Hay una regla cuando debemos usar los tipos Unicode?
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 VARCHAR.
Estoy buscando algo como:
- Si tienes chino - > utilizar NVARCHAR
- Si tiene alemán y árabe - > utilizar NVARCHAR
¿Qué pasa con la recopilación del servidor / base de datos?
No quiero usar siempre NVARCHAR como se sugiere aquí ¿Cuáles son las principales diferencias de rendimiento entre los tipos de datos varchar y nvarchar de SQL Server?
Solución
La verdadera razón por la que desea usar NVARCHAR es que cuando tenga idiomas diferentes en la misma columna, debe direccionar las columnas en T-SQL sin descodificar, quiere poder ver el datos " nativamente " en SSMS, o desea estandarizar en Unicode.
Si trata la base de datos como almacenamiento estúpido, 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 diferentes filas. También significa que el servidor SQL no podrá tratar los datos fácilmente para 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 y que esté relativamente sin restricciones.
Recomendaría VARCHAR para cualquier columna que sea una clave natural (como una placa de vehículo, SSN, número de serie, etiqueta de servicio, número de pedido, indicativo de aeropuerto, etc.) que está típicamente definido y restringido por una norma o legislación o convención. También VARCHAR para usuarios ingresados ??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 esos.
Así que para una regla simple:
VARCHAR cuando se garantiza que está restringido NVARCHAR de lo contrario
Otros consejos
Debe usar NVARCHAR siempre que tenga que almacenar múltiples idiomas. Creo que tienes que usarlo para los idiomas asiáticos, pero no me cites.
Este es el problema si toma ruso, por ejemplo, y lo almacena en un varchar, estará bien siempre que defina la página de códigos correcta. Pero digamos que está utilizando una instalación de sql de inglés predeterminada, entonces los caracteres rusos no se manejarán correctamente. Si estuviera utilizando NVARCHAR (), se manejarían correctamente.
Editar
Ok, déjame citar MSDN y tal vez lo hice específico, pero no desea almacenar más de una página de códigos en una columna varcar, mientras que puede no debe
Cuando tratas con datos de texto que son almacenado en el char, varchar, varchar (max), o tipo de datos de texto, el limitación más importante a considerar Es que solo información de un solo página de códigos puede ser validada por el sistema. (Puede almacenar datos de múltiples páginas de códigos, pero esto no es recomendado.) La página de códigos exacta utilizada Para validar y almacenar los datos depende en el cotejo de la columna. Si un La colación a nivel de columna no ha sido definido, el cotejo de la base de datos se utiliza Para determinar la página de códigos. que se usa para una columna dada, tu puede usar la 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 lugares, como georgiano y Hindi, no tienen páginas de códigos, ya que son colaciones de Unicode solamente. Aquellos las colaciones no son apropiadas para columnas que utilizan el char, varchar, o tipo de datos de texto
Así que el georgiano o el hindi realmente necesitan ser almacenados como nvarchar. El árabe también es un problema:
Otro problema que puede encontrar es La incapacidad para almacenar datos cuando no todos los personajes que desees El soporte está contenido en el código. página. En muchos casos, Windows considera una página de códigos en particular para ser un " mejor encajar " página de códigos, lo que significa que hay No hay garantía de que pueda confiar en el 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 gama de idiomas, incluyendo Baluchi, Berber, Farsi, Kashmiri, Kazajo, Kirghiz, Pashto, Sindhi, uigur, urdu, y más. Todo estos idiomas tienen adicional personajes más allá de los del árabe Idioma como se define en el código de Windows página 1256. Si intentas almacenar estos personajes extra en una columna no Unicode que tiene el árabe colación, los personajes son convertido en signos de interrogación.
Algo que se debe tener en cuenta cuando se usa Unicode, aunque puede almacenar diferentes idiomas en una sola columna, solo se puede clasificar utilizando una sola intercalación. Hay algunos idiomas que usan caracteres latinos pero no se clasifican como otros idiomas latinos. Los acentos son un buen ejemplo de esto, no puedo recordar el ejemplo, pero hubo un idioma de Europa del Este cuya Y no se parecía a la Y en inglés. Luego está el idioma español que los usuarios españoles esperan que se clasifique después de h.
En definitiva, con todos los problemas con los que tiene que lidiar cuando se trata de la internalización. Es mi opinión que es más fácil usar solo caracteres Unicode desde el principio, evitar las conversiones adicionales y aprovechar el espacio. De ahí mi declaración anterior.
Griego necesitaría UTF-8 en los tipos de columna N: aß?;)
Josh dice: " .... Algo que se debe tener en cuenta cuando se usa Unicode, aunque puede almacenar diferentes idiomas en una sola columna, solo se puede clasificar utilizando una sola intercalación. Hay algunos idiomas que usan 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 era como la Y en inglés. Luego está el ch en español que los usuarios españoles esperan que se clasifique después de h. & Quot ;
Soy un 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 en ñ o en HTML " & amp; ntilde; "
Alex
TL; DR;
Unicode - (nchar, nvarchar y ntext)
No Unicode - (char, varchar, y texto).
Las clasificaciones en SQL Server proporcionan reglas de clasificación, caso y acento Propiedades de sensibilidad para sus datos. Las colaciones 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.
Suponiendo que esté utilizando la intercalación de SQL por defecto SQL_Latin1_General_CP1_CI_AS
, a continuación, el siguiente script debe imprimir todos los símbolos que puede incluir 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 la intercalación por decir japonés, notará que todas las letras europeas extrañas se convirtieron en normales y algunos símbolos en marcas ?
.
Unicode es un estándar para asignar puntos de código a caracteres. Porque Está diseñado para cubrir todos los caracteres de todos los idiomas de la mundo, no hay necesidad de diferentes páginas de códigos para manejar diferentes Conjuntos de personajes. 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 que no son Unicode (char, varchar y text).
De lo contrario, tu clasificación será rara.