¿Cuál es la diferencia entre char, nchar, varchar y nvarchar en SQL Server?

625

¿Qué se entiende por nvarchar?

¿Cuál es la diferencia entre char, nchar, varchary nvarcharen SQL Server?

MrDatabase
fuente

Respuestas:

859

Solo para aclarar ... o resumir ...

  • nchary nvarcharpuede almacenar caracteres Unicode .
  • chary no puede almacenar caracteres Unicode .varchar
  • chary nchartienen una longitud fija que reservará espacio de almacenamiento para la cantidad de caracteres que especifique, incluso si no usa todo ese espacio.
  • varchary nvarchartienen una longitud variable que solo usará espacios para los caracteres que almacene. No reservará almacenamiento como charonchar .

nchary nvarcharocupará el doble de espacio de almacenamiento, por lo que puede ser conveniente usarlos solo si necesita soporte Unicode .

Brian Kim
fuente
15
char y varchar no están destinados a almacenar unicode, pero con algunos trucos de codificación adicionales y lógica adicional, aún puede utilizar incorrectamente un campo [var] char para el almacenamiento unicode.
Wim ten Brink
10
Depende de la clasificación si las n...versiones ocupan o no el doble de espacio de almacenamiento que muestra mi respuesta
Martin Smith
77
¿Cuál es la ventaja de reservar almacenamiento?
mlissner
44
En el último punto: el uso de Unicode nchar y nvarchar son aún mejores en la mayoría de los casos, una mejor clasificación, flexibilidad para los usuarios, elimina futuros problemas de compatibilidad. Y, por cierto, el espacio de almacenamiento no es un problema para este caso, ya que usar la intercalación sin Unicode es muy complicado, y las tasas de memoria continuarán disminuyendo en el futuro
Jaison Varghese
66
@BenCaine char (20) usará 20 bytes (suponiendo una intercalación de 8 bits); varchar (20) usará len (datos) +2 bytes, es decir, 22 para 20 bytes de datos, pero solo 12 para 10 bytes de datos. Los dos bytes adicionales son los registros de longitud. Si sus datos siempre serán completos, use un carácter, ya que ahorra espacio y puede ser más rápido. Por favor, nunca use un varchar (1), o de hecho algo más pequeño que un varchar (4). Un solo carácter en formato varchar usa tres bytes, por lo que un char (3) nunca usará más espacio que un varchar (3).
Richard Gadsden
95

Todas las respuestas hasta ahora indican que varchares de un solo byte, nvarchar es de doble byte. La primera parte de esto realmente depende de la recopilación como se ilustra a continuación.

DECLARE @T TABLE
(
C1 VARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS,
C2 NVARCHAR(20)COLLATE  Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS
)

INSERT INTO @T 
    VALUES (N'中华人民共和国',N'中华人民共和国'),
           (N'abc',N'abc');

SELECT C1,
       C2,
       LEN(C1)        AS [LEN(C1)],
       DATALENGTH(C1) AS [DATALENGTH(C1)],
       LEN(C2)        AS [LEN(C2)],
       DATALENGTH(C2) AS [DATALENGTH(C2)]
FROM   @T  

Devoluciones

ingrese la descripción de la imagen aquí

Tenga en cuenta que el y los caracteres aún no estaban representados en la VARCHARversión y se reemplaza con silencio ?.

En realidad, todavía no hay caracteres chinos que puedan ser representados por un solo byte en esa clasificación. Los únicos caracteres de un solo byte son el conjunto ASCII occidental típico.

Debido a esto, es posible que una inserción de una nvarchar(X)columna a una varchar(X)columna falle con un error de truncamiento (donde X denota un número que es el mismo en ambas instancias).

SQL Server 2012 agrega intercalaciones SC (caracteres suplementarios) que admiten UTF-16. En estas intercalaciones, un solo nvarcharcarácter puede tomar 2 o 4 bytes.

Martin Smith
fuente
44
El tipo de respuesta que estaba buscando. También para ahorrar tiempo a personas como yo: el texto que no está en inglés se traduce como "República Popular de China" translate.google.com/#auto/en/…
Igand
34

nchar y char funcionan prácticamente de la misma manera que los demás, al igual que nvarchar y varchar. La única diferencia entre ellos es que nchar / nvarchar almacena caracteres Unicode (esencial si requiere el uso de conjuntos de caracteres extendidos) mientras que varchar no.

Debido a que los caracteres Unicode requieren más almacenamiento, los campos nchar / nvarchar ocupan el doble de espacio (por ejemplo, en versiones anteriores de SQL Server, el tamaño máximo de un campo nvarchar es 4000).

Esta pregunta es un duplicado de esta .

Luke Bennett
fuente
3
Olvida una cosa: nchar utiliza una longitud fija, por lo que nchar (10) siempre necesita recibir diez caracteres. Y varchar (10) es de hecho Unicode y aceptará cualquier número de caracteres, hasta 10 caracteres. También vea msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink el
33

Solo para agregar algo más: nchar : agrega espacios finales a los datos. nvarchar : no agrega espacios finales a los datos.

Por lo tanto, si va a filtrar su conjunto de datos por un campo 'nchar', puede usar RTRIM para eliminar los espacios. Por ejemplo, el campo nchar (10) llamado BRAND almacena la palabra NIKE. Agrega 6 espacios a la derecha de la palabra. Entonces, al filtrar, la expresión debería leer: RTRIM (Fields! BRAND.Value) = "NIKE"

¡Espero que esto ayude a alguien por ahí porque estaba luchando con eso por un momento!

Dimuthu
fuente
24

Mi intento de resumir y corregir las respuestas existentes:

En primer lugar, chary ncharsiempre va a utilizar una cantidad fija de espacio de almacenamiento, incluso cuando la cadena a ser almacenado es menor que el espacio disponible, mientras que varchary nvarcharse utilice sólo como espacio de almacenamiento tanto como sea necesario para almacenar esa cadena (más dos bytes de sobrecarga, presumiblemente para almacenar la longitud de la cadena). Entonces recuerde, "var" significa "variable", como en el espacio variable.

El segundo punto importante a entender es eso, nchary nvarcharalmacenar cadenas usando exactamente dos bytes por carácter, mientras que chary varcharusar una codificación determinada por la página de códigos de clasificación, que generalmente será exactamente un byte por carácter (aunque hay excepciones, ver más abajo). Al usar dos bytes por carácter, se puede almacenar un rango muy amplio de caracteres, por lo que lo básico a recordar aquí es eso nchary nvarchartiende a ser una opción mucho mejor cuando se necesita soporte de internacionalización, lo que probablemente se haga.

Ahora para algunos puntos más finos.

Primero, nchary las nvarcharcolumnas siempre almacenan datos usando UCS-2. Esto significa que se utilizarán exactamente dos bytes por carácter, y cualquier carácter Unicode en el plano multilingüe básico (BMP) puede almacenarse mediante un campo ncharo nvarchar. Sin embargo, no se puede almacenar ningún carácter Unicode. Por ejemplo, según Wikipedia, los puntos de código para los jeroglíficos egipcios quedan fuera del BMP. Por lo tanto, hay cadenas Unicode que se pueden representar en UTF-8 y otras codificaciones Unicode verdaderas que no se pueden almacenar en un servidor ncharo nvarcharcampo SQL , y las cadenas escritas en jeroglíficos egipcios estarían entre ellas. Afortunadamente, sus usuarios probablemente no escriban en ese script, ¡pero es algo a tener en cuenta!

Otro punto interesante confuso, pero que otros críticos se han puesto de manifiesto que es chary varcharcampos pueden usar dos bytes por carácter para ciertos caracteres si la página de códigos de colación lo requiere. (Martin Smith da un excelente ejemplo en el que muestra cómo Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS exhibe este comportamiento. Compruébelo).

ACTUALIZACIÓN: a partir de SQL Server 2012, finalmente hay páginas de códigos para UTF-16 , por ejemplo Latin1_General_100_CI_AS_SC, que realmente pueden cubrir todo el rango Unicode.

PeterAllenWebb
fuente
14
  • char: datos de caracteres de longitud fija con una longitud máxima de 8000 caracteres.
  • nchar: datos unicode de longitud fija con una longitud máxima de 4000 caracteres.
  • Char = Longitud de 8 bits
  • NChar = Longitud de 16 bits
ss.
fuente
charno podría tener una longitud de 8 bits. No tiene que almacenar la longitud, y la longitud fija puede ser de hasta 8000 caracteres.
John B. Lambe
12

nchar[(n)] (caracter nacional)

  • Datos de cadena Unicode de longitud fija .
  • n define la longitud de la cadena y debe ser un valor de 1 a 4.000.
  • El tamaño de almacenamiento es dos veces nbytes.

nvarchar [(n | max)] (El carácter nacional varía).

  • Datos de cadena Unicode de longitud variable .
  • n define la longitud de la cadena y puede ser un valor de 1 a 4,000.
  • max indica que el tamaño máximo de almacenamiento es 2 ^ 31-1 bytes (2 GB).
  • El tamaño de almacenamiento, en bytes, es dos veces la longitud real de los datos ingresados ​​+ 2 bytes

char [(n)] (personaje)

  • Longitud fija, non-Unicodedatos de cadena.
  • n define la longitud de la cadena y debe ser un valor de 1 a 8,000.
  • El tamaño de almacenamiento es nbytes.

varchar [(n | max)] (carácter variable)

  • Datos de cadena de longitud variable, no Unicode .
  • n define la longitud de la cadena y puede ser un valor de 1 a 8,000.
  • max indica que el tamaño máximo de almacenamiento es 2 ^ 31-1 bytes (2 GB).
  • El tamaño de almacenamiento es la longitud real de los datos ingresados ​​+ 2 bytes.
Rasel
fuente
7

Las diferencias son:

  1. n [var] char almacena unicode mientras que [var] char solo almacena caracteres de un byte.
  2. [n] char requiere un número fijo de caracteres de la longitud exacta, mientras que [n] varchar acepta un número variable de caracteres hasta e incluyendo la longitud definida.

Otra diferencia es la longitud. Tanto nchar como nvarchar pueden tener hasta 4.000 caracteres de longitud. Y char y varchar pueden tener hasta 8000 caracteres de longitud. Pero para SQL Server también puede usar un [n] varchar (max) que puede manejar hasta 2,147,483,648 caracteres. (Dos gigabytes, un entero de 4 bytes firmado).

Wim ten Brink
fuente
7

nchar requiere más espacio que nvarchar.

p.ej,

Un nchar (100) siempre almacenará 100 caracteres, incluso si solo ingresa 5, los 95 caracteres restantes se rellenarán con espacios. El almacenamiento de 5 caracteres en un nvarchar (100) ahorrará 5 caracteres.

Venkataraman R
fuente
66
No es completamente cierto, ya que debe completar un carácter (100) con hasta 100 caracteres. Utilizaría esto cuando, por ejemplo, almacene números de teléfono en su base de datos o pida números con una longitud fija. Debido a que la longitud del campo es fija, no tiene otra opción para llenarla hasta el número máximo de caracteres. Pero cuando todos sus datos son de 100 caracteres por registro, un char (100) ocupará menos almacenamiento que un varchar (100) porque no necesita una indicación de longitud: cada valor sería exactamente de 100 caracteres.
Wim ten Brink
5

nchar (10) es una cadena Unicode de longitud fija de longitud 10. nvarchar (10) es una cadena Unicode de longitud variable con una longitud máxima de 10. Normalmente, usaría el primero si todos los valores de datos son 10 caracteres y el último Si las longitudes varían.

Jason Kresowaty
fuente
Comparación incorrecta: la pregunta se refiere a nchar y varchar, no a nchar y nvarchar.
Luke Bennett
4
  • nchar es de longitud fija y puede contener caracteres unicode. Utiliza dos bytes de almacenamiento por carácter.

  • varchar es de longitud variable y no puede contener caracteres unicode. Utiliza un almacenamiento de bytes por carácter.

Manu
fuente
Incorrecto. Unicode puede usar de 1 a 4 bytes (en general) para cada carácter. Además, un varchar puede contener unicode, pero no se reconoce como unicode. Como resultado, un varchar se considera poco confiable para el almacenamiento unicode. (Especialmente porque existe el riesgo de que el código que accede al campo lo traduzca incorrectamente.)
Wim ten Brink
@ Alex: Creo que has dicho tu punto pero todavía no estoy de acuerdo contigo. Lo que está diciendo es que un int PUEDE retener un largo si el largo es menor que 2 ^ 32. Esto no solo es "poco confiable", es una limitación inherente que hace imposible cubrir todo el rango de valores.
Manu
44
@ Taller Alex: Mal. Unicode codificado como UCS-2(que pasa a ser la codificación utilizada por SQL Server) almacena todos los personajes en exactamente dos bytes, ver msdn.microsoft.com/en-us/library/bb330962%28v=sql.90%29.aspx : SQL Server stores Unicode in the UCS-2 encoding scheme... UCS-2 is a fixed-length encoding that represents all characters as a 16-bit value (2 bytes). SQL Server 2008 puede usar la compresión SCSU, pero sigue siendo compresión de las cadenas Unicode codificadas en UCS-2: msdn.microsoft.com/en-us/library/ee240835.aspx
Remus Rusanu
2

NVARCHAR puede almacenar caracteres Unicode y ocupa 2 bytes por carácter.

Gustavo Rubio
fuente
1
¡INCORRECTO! ¡Unicode usa entre 1 y 4 bytes por carácter! ¡Mucha gente olvida esto! Incluso el uso de UTF-16 podría dar como resultado que algunos caracteres tomen 4 bytes en lugar de 2, aunque la longitud común será de 2 bytes. ¡Ciertos otros subformatos de Unicode pueden tomar incluso más de 4 bytes!
Wim ten Brink
77
@WimtenBrink: la pregunta es sobre SQL Server y nvarcharsiempre toma 2 bytes por carácter.
Martin Smith
@Wim, tienes razón, hay varias codificaciones para Unicode que pueden producir un número diferente de bytes. Pero SQL Server no le da una opción sobre la codificación Unicode. SQL Server antes de 2012 solo usaba UCS-2, de dos bytes de ancho, por lo que Martin estaba en lo correcto al momento de escribir la respuesta. Como han dicho otras respuestas anteriores, SQL Server 2012 ahora proporciona UTF-16, por lo que dos bytes para muchos caracteres (aquellos en el plano multilenguaje básico Unicode), cuatro bytes para otros.
Concrete Gannet