Qual é a diferença entre char, nchar, varchar e nvarchar no SQL Server?

623

O que se entende por nvarchar?

Qual é a diferença entre char, nchar, varchar, e nvarcharno SQL Server?

MrDatabase
fonte

Respostas:

857

Apenas para esclarecer ... ou resumir ...

  • nchare nvarcharpode armazenar caracteres Unicode .
  • chare não pode armazenar caracteres Unicode .varchar
  • chare ncharsão de comprimento fixo, que reservam espaço de armazenamento para o número de caracteres que você especificar, mesmo se você não usar todo esse espaço.
  • varchare nvarcharsão de tamanho variável, que só ocupam espaços para os caracteres que você armazena. Não reservará armazenamento como charounchar .

nchare nvarcharocupará o dobro do espaço de armazenamento; portanto, é aconselhável usá-los apenas se você precisar de suporte Unicode .

Brian Kim
fonte
15
char e varchar não servem para armazenar unicode, mas com alguns truques adicionais de codificação e lógica extra, você ainda pode usar indevidamente um campo [var] char para armazenamento unicode.
Wim ten Brink
10
É dependente agrupamento ou não as n...versões levar até duas vezes mais espaço de armazenamento como minha resposta mostra
Martin Smith
7
Qual é a vantagem de reservar armazenamento?
mlissner
4
No último ponto: o uso de Unicode nchar e nvarchar ainda é melhor na maioria dos casos, melhor agrupamento, flexibilidade para os usuários e remove futuros problemas de compatibilidade. E, a propósito, o espaço de armazenamento não é um problema para esse caso, pois o uso do agrupamento sem Unicode é muito trabalhoso e as taxas de memória continuarão a diminuir no futuro
Jaison Varghese
6
O @BenCaine char (20) usará 20 bytes (assumindo um agrupamento de 8 bits); varchar (20) usará len (dados) +2 bytes, ou seja, 22 para 20 bytes de dados, mas apenas 12 para 10 bytes de dados. Os dois bytes extras são os registros de comprimento. Se seus dados sempre tiverem o tamanho total, use um caractere, pois economiza espaço e pode ser mais rápido. Por favor, nunca use um varchar (1) ou qualquer coisa menor que um varchar (4). Um único caractere no formato varchar usa três bytes, portanto, um char (3) nunca usará mais espaço que um varchar (3).
9788 Richard Gásden
95

Todas as respostas até agora indicam que varcharé um byte único, nvarchar é um byte duplo. A primeira parte disso realmente depende da intercalação, como ilustrado abaixo.

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  

Devoluções

insira a descrição da imagem aqui

Observe que os caracteres e ainda não foram representados na VARCHARversão e foram substituídos silenciosamente por ?.

Na verdade, ainda não existem caracteres chineses que possam ser reprocessados ​​por um único byte nesse agrupamento. Os únicos caracteres de byte único são o conjunto ASCII ocidental típico.

Por esse motivo, é possível inserir um nvarchar(X) coluna em uma varchar(X)coluna falhe com um erro de truncamento (onde X indica um número igual nas duas instâncias).

O SQL Server 2012 adiciona agrupamentos de SC (caracteres suplementares) compatíveis UTF-16. Nesses agrupamentos, um único nvarcharcaractere pode levar 2 ou 4 bytes.

Martin Smith
fonte
4
O tipo de resposta que eu estava procurando. Também para poupar tempo ao gosta de mim - o texto não-Inglês traduz a "República Popular da China" translate.google.com/#auto/en/...
Igand
34

nchar e char funcionam praticamente da mesma maneira que os outros, assim como nvarchar e varchar. A única diferença entre eles é que o nchar / nvarchar armazena caracteres Unicode (essencial se você precisar do uso de conjuntos de caracteres estendidos), enquanto o varchar não.

Como os caracteres Unicode requerem mais armazenamento, os campos nchar / nvarchar ocupam o dobro do espaço (por exemplo, nas versões anteriores do SQL Server, o tamanho máximo de um campo nvarchar é 4000).

Esta pergunta é uma duplicata desta .

Luke Bennett
fonte
3
Você esquece uma coisa: o nchar usa um comprimento fixo, portanto o nchar (10) sempre precisa receber dez caracteres. E varchar (10) é realmente Unicode e aceitará qualquer número de caracteres, até 10 caracteres. Veja também msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink
33

Apenas para adicionar algo mais: nchar - adiciona espaços finais aos dados. nvarchar - não adiciona espaços finais aos dados.

Portanto, se você deseja filtrar seu conjunto de dados por um campo 'nchar', convém usar o RTRIM para remover os espaços. Por exemplo, o campo nchar (10) chamado BRAND armazena a palavra NIKE. Adiciona 6 espaços à direita da palavra. Portanto, ao filtrar, a expressão deve ser: RTRIM (Fields! BRAND.Value) = "NIKE"

Espero que isso ajude alguém lá fora, porque eu estava lutando com isso um pouco agora!

Dimuthu
fonte
24

Minha tentativa de resumir e corrigir as respostas existentes:

Em primeiro lugar, chare ncharsempre usará uma quantidade fixa de espaço de armazenamento, mesmo quando a corda a ser armazenado é menor do que o espaço disponível, enquanto que varcharenvarchar vai utilizar apenas a quantidade de espaço de armazenamento, como é necessário para armazenar essa cadeia (mais dois bytes de sobrecarga, presumivelmente para armazenar o comprimento da corda). Então lembre-se, "var" significa "variável", como no espaço variável.

O segundo ponto importante a entender é que, nchare nvarchararmazene seqüências de caracteres usando exatamente dois bytes por caractere, chare varcharuse uma codificação determinada pela página de códigos de intercalação, que geralmente será exatamente um byte por caractere (embora haja exceções, veja abaixo). Ao usar dois bytes por caractere, uma variedade muito ampla de caracteres pode ser armazenada; portanto, o básico a ser lembrado aqui é esse nchare nvarchartende a ser uma escolha muito melhor quando você deseja suporte à internacionalização, o que provavelmente o faz.

Agora, alguns pontos mais delicados.

Em primeiro lugar, nchare nvarcharcolunas sempre armazenar dados usando UCS-2. Isso significa que exatamente dois bytes por caractere serão usados ​​e qualquer caractere Unicode no BMP (Basic Multilingual Plane) pode ser armazenado por um campo ncharou nvarchar. No entanto, não é possível que qualquer caractere Unicode possa ser armazenado. Por exemplo, de acordo com a Wikipedia, os pontos de código para hieróglifos egípcios ficam fora do BMP. Portanto, existem cadeias Unicode que podem ser representadas em UTF-8 e outras codificações Unicode verdadeiras que não podem ser armazenadas em um SQL Server ncharou nvarcharcampo, e as cadeias escritas em hieróglifos egípcios estariam entre elas. Felizmente, seus usuários provavelmente não escrevem nesse script, mas é algo a ter em mente!

Outro ponto confuso, mas interessante, que outros pôsteres destacaram é que os campos chare varcharpodem usar dois bytes por caractere para determinados caracteres, se a página de código de intercalação exigir. (Martin Smith dá um excelente exemplo no qual ele mostra como Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS exibe esse comportamento. Confira.)

ATUALIZAÇÃO: A partir do SQL Server 2012, finalmente existem páginas de código para UTF-16 , por exemplo, Latin1_General_100_CI_AS_SC, que pode realmente cobrir todo o intervalo Unicode.

PeterAllenWebb
fonte
14
  • char: dados de caracteres de comprimento fixo com um comprimento máximo de 8000 caracteres.
  • nchar: dados unicode de comprimento fixo com um comprimento máximo de 4000 caracteres.
  • Char = Comprimento de 8 bits
  • NChar = Comprimento de 16 bits
ss.
fonte
charnão poderia ter um comprimento de 8 bits. Não é necessário armazenar o comprimento, e o comprimento fixo pode ter até 8000 caracteres.
John B. Lambe
12

nchar[(n)] (figura nacional)

  • Dados de cadeia Unicode de comprimento fixo .
  • n define o comprimento da sequência e deve ser um valor de 1 a 4.000.
  • O tamanho do armazenamento é duas vezes nbytes.

nvarchar [(n | max)] (caráter nacional variando.)

  • Dados de seqüência de caracteres Unicode de comprimento variável .
  • n define o comprimento da string e pode ser um valor de 1 a 4.000.
  • max indica que o tamanho máximo de armazenamento é 2 ^ 31-1 bytes (2 GB).
  • O tamanho do armazenamento, em bytes, é duas vezes o comprimento real dos dados inseridos + 2 bytes

char [(n)] (personagem)

  • non-UnicodeDados de string de comprimento fixo .
  • n define o comprimento da sequência e deve ser um valor de 1 a 8.000.
  • O tamanho do armazenamento é nbytes.

varchar [(n | max)] (caracteres variados)

  • Dados de seqüência não Unicode de comprimento variável .
  • n define o comprimento da string e pode ser um valor de 1 a 8.000.
  • max indica que o tamanho máximo de armazenamento é 2 ^ 31-1 bytes (2 GB).
  • O tamanho do armazenamento é o comprimento real dos dados inseridos + 2 bytes.
Rasel
fonte
7

As diferenças são:

  1. n [var] char armazena unicode enquanto [var] char apenas armazena caracteres de byte único.
  2. [n] char requer um número fixo de caracteres do tamanho exato, enquanto [n] varchar aceita um número variável de caracteres até e incluindo o comprimento definido.

Outra diferença é o comprimento. O nchar e o nvarchar podem ter até 4.000 caracteres. E char e varchar podem ter até 8000 caracteres. Mas para o SQL Server, você também pode usar um [n] varchar (max) que pode manipular até 2.147.483.648 caracteres. (Dois gigabytes, um número inteiro de 4 bytes assinado.)

Wim ten Brink
fonte
7

nchar requer mais espaço que nvarchar.

por exemplo,

Um nchar (100) sempre armazenará 100 caracteres, mesmo se você digitar apenas 5, os 95 caracteres restantes serão preenchidos com espaços. Armazenar 5 caracteres em um nvarchar (100) salvará 5 caracteres.

Venkataraman R
fonte
6
Não é totalmente verdade, pois você precisa preencher um caractere (100) com até 100 caracteres. Você usaria isso quando estiver, por exemplo, armazenando números de telefone em seu banco de dados ou solicitando números com um comprimento fixo. Como o tamanho do campo é fixo, você não pode escolher preenchê-lo com o número máximo de caracteres. Mas quando todos os seus dados tiverem 100 caracteres por registro, um caractere (100) ocupará menos espaço que um varchar (100) porque não precisa de uma indicação de comprimento: todo valor teria exatamente 100 caracteres.
Wim ten Brink
5

nchar (10) é uma cadeia de caracteres Unicode de comprimento fixo 10. nvarchar (10) é uma cadeia de caracteres Unicode de comprimento variável com um comprimento máximo de 10. Normalmente, você usaria a primeira se todos os valores de dados tiverem 10 caracteres e a segunda se os comprimentos variarem.

Jason Kresowaty
fonte
Comparação errada - a questão está relacionada a nchar e varchar, não nchar e nvarchar.
Luke Bennett
4
  • nchar é de tamanho fixo e pode conter caracteres unicode. usa dois bytes de armazenamento por caractere.

  • varchar é de tamanho variável e não pode conter caracteres unicode. ele usa um armazenamento de bytes por caractere.

Manu
fonte
Errado. O Unicode pode usar 1 a 4 bytes (em geral) para cada caractere. Além disso, um varchar pode conter unicode, mas não é reconhecido como unicode. Como resultado, um varchar é considerado não confiável para armazenamento unicode. (Especialmente porque há um risco de que o código que acessa o campo irá traduzi-lo incorretamente.)
Wim ten Brink
@ Alex: Eu acho que você fez o seu ponto, mas eu ainda não concordo com você. O que você está dizendo é que um int PODE manter um longo se o longo for menor que 2 ^ 32. Isso não é apenas 'não confiável', é uma limitação inerente que torna impossível cobrir todo o intervalo de valores.
Manu
4
@Workshop Alex: Errado. Unicode codificado como UCS-2(que passa a ser a codificação usada pelo SQL Server) armazena cada personagem exatamente dois bytes, consulte 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 pode usar compressão SCSU, mas ainda é a compressão dos UCS-2 cadeias de caracteres Unicode codificados: msdn.microsoft.com/en-us/library/ee240835.aspx
Remus Rusanu
2

O NVARCHAR pode armazenar caracteres Unicode e usa 2 bytes por caractere.

Gustavo Rubio
fonte
1
ERRADO! O Unicode usa entre 1 e 4 bytes por caractere! Muitas pessoas esquecem isso! Até o uso de UTF-16 pode resultar em alguns caracteres com 4 bytes em vez de 2, embora o comprimento comum seja de 2 bytes. Certos outros subformatos do Unicode podem levar até mais de 4 bytes!
Wim ten Brink
7
@WimtenBrink - A questão é sobre o SQL Server e nvarcharsempre leva 2 bytes por caractere.
Martin Smith
@Wim, você está correto, existem várias codificações para Unicode que podem produzir um número diferente de bytes. Mas o SQL Server não oferece uma opção sobre a codificação Unicode. O SQL Server anterior a 2012 usava apenas o UCS-2, com dois bytes de largura; portanto, Martin estava correto no momento em que escreveu a resposta. Como outras respostas acima disseram, o SQL Server 2012 agora fornece UTF-16, portanto, dois bytes para muitos caracteres (aqueles no Plano Multilíngüe Básico Unicode), quatro bytes para outros.
Concrete Gannet