Estou trabalhando em um banco de dados para um pequeno aplicativo Web na minha escola usando SQL Server 2005
.
Vejo algumas escolas de pensamento sobre a questão do varchar
vs nvarchar
:
- Use, a
varchar
menos que você lide com muitos dados internacionalizados, depois usenvarchar
. - Basta usar
nvarchar
para tudo.
Estou começando a ver os méritos da visão 2. Sei que o nvarchar ocupa duas vezes mais espaço, mas isso não é necessariamente um grande negócio, pois isso só vai armazenar dados para algumas centenas de estudantes. Para mim, parece que seria mais fácil não se preocupar com isso e permitir que tudo usasse o nvarchar. Ou há algo que estou perdendo?
sql-server
sql-server-2005
storage
varchar
nvarchar
Jason Baker
fonte
fonte
NVARCHAR
" e pode ter impactos muito negativos no desempenho e nos custos / orçamentos de hardware. Algumas linhas, até alguns milhares, não importam. Como os sistemas crescem mais rapidamente do que as pessoas esperam, a resposta atual aceita é um desserviço à comunidade. Obrigado.Respostas:
Sempre use nvarchar.
Você pode nunca precisar dos caracteres de byte duplo para a maioria dos aplicativos. No entanto, se você precisar oferecer suporte a idiomas de byte duplo e tiver suporte a byte único no esquema do banco de dados, é muito caro voltar e modificar em todo o aplicativo.
O custo da migração de um aplicativo de varchar para nvarchar será muito mais do que o pouco de espaço em disco extra que você utilizará na maioria dos aplicativos.
fonte
Espaço em disco não é o problema ... mas a memória e o desempenho serão. Dobra a leitura da página, tamanho de índice duplo, LIKE estranho e = comportamento constante etc
Você precisa armazenar scripts etc em chinês? Sim ou não...
E do MS BOL " Efeitos de armazenamento e desempenho do Unicode "
Editar :
Pergunta recente do SO que destaca o desempenho ruim do nvarchar ...
O SQL Server usa alta CPU ao pesquisar dentro de cadeias de caracteres nvarchar
fonte
Ser consistente! Juntar um VARCHAR ao NVARCHAR tem um grande impacto no desempenho.
fonte
nvarchar
avarchar
vs converternvarchar
paravarchar
e juntando-se avarchar
. A menos que, claro, você quisesse ser consistente nos tipos de dados da coluna, não na junção.VARCHAR
eNVARCHAR
isso deve ser devido à indexação daVARCHAR
coluna, juntamente com o tipo de agrupamento usado para essa coluna (e, portanto, o índice). Abordo este tópico em detalhes na seguinte postagem no blog: Impacto nos índices ao misturar os tipos VARCHAR e NVARCHAR .O nvarchar terá uma sobrecarga significativa na memória, armazenamento, conjunto de trabalho e indexação; portanto, se as especificações determinarem que realmente nunca será necessário, não se preocupe.
Eu não teria uma regra rígida e rápida "sempre nvarchar" porque pode ser um desperdício completo em muitas situações - particularmente ETL de ASCII / EBCDIC ou identificadores e colunas de código que geralmente são chaves e chaves estrangeiras.
Por outro lado, existem muitos casos de colunas, onde eu faria essa pergunta mais cedo e, se não obtivesse uma resposta rápida e imediata, tornaria a coluna nvarchar.
fonte
Hesito em acrescentar mais uma resposta aqui, pois já existem algumas, mas é preciso ressaltar alguns pontos que ainda não foram feitos ou que não foram feitos claramente.
Primeiro: Do não usar sempre
NVARCHAR
. Essa é uma atitude / abordagem muito perigosa e muitas vezes dispendiosa. E não é melhor dizer " Nunca use cursores", pois às vezes eles são os meios mais eficientes de resolver um problema específico, e a solução comum de fazer umWHILE
loop quase sempre será mais lenta do que um Cursor feito corretamente .O único momento em que você deve usar o termo "sempre" é quando aconselhado a "sempre fazer o que é melhor para a situação". É óbvio que é difícil determinar, principalmente quando se tenta equilibrar os ganhos de curto prazo no tempo de desenvolvimento (gerente: "precisamos desse recurso - que você não conhecia até agora - uma semana atrás!") Por muito tempo. custos de manutenção a médio prazo (gerente que inicialmente pressionou a equipe para concluir um projeto de 3 meses em um sprint de 3 semanas: "por que estamos tendo esses problemas de desempenho? Como poderíamos ter feito o X sem flexibilidade? Não podemos pagar um sprint ou dois para corrigir isso. O que podemos fazer em uma semana para voltar aos itens prioritários? E, definitivamente, precisamos gastar mais tempo no design para que isso não continue acontecendo! ").
Segundo: a resposta do @ gbn aborda alguns pontos muito importantes a serem considerados ao tomar determinadas decisões de modelagem de dados quando o caminho não está 100% claro. Mas há ainda mais a considerar:
A perda de espaço tem um enorme efeito cascata em todo o sistema. Eu escrevi um artigo entrando em detalhes explícitos sobre este tópico: O disco é barato! ORLY? (é necessário registro gratuito; desculpe-me por não controlar essa política).
Terceiro: enquanto algumas respostas estão incorretamente focadas no aspecto "este é um aplicativo pequeno" e outras estão sugerindo corretamente "usar o que é apropriado", nenhuma das respostas forneceu orientações reais ao OP Um detalhe importante mencionado na pergunta é que esta é uma página da web da escola deles. Ótimo! Então, podemos sugerir que:
NVARCHAR
, pois, com o tempo, é cada vez mais provável que nomes de outras culturas sejam exibidos nesses locais.VARCHAR
a Página de Código apropriada (que é determinado a partir do agrupamento do campo).INT
/TINYINT
já que os códigos ISO são de comprimento fixo, legíveis por humanos e padrão): useCHAR(2)
para códigos de duas letras eCHAR(3)
se estiver usando três códigos de letras. E considere usar um agrupamento binário comoLatin1_General_100_BIN2
.VARCHAR
pois é um padrão internacional nunca usar nenhuma letra fora de AZ. E sim, ainda use,VARCHAR
mesmo que apenas armazene códigos postais dos EUA e não INT, pois os códigos postais não são números, são cadeias de caracteres e alguns deles têm um "0" inicial. E considere usar um agrupamento binário comoLatin1_General_100_BIN2
.NVARCHAR
dois agora que podem conter caracteres Unicode.Quarto: agora que você tem
NVARCHAR
dados que ocupam o dobro do espaço necessário para dados que se encaixam perfeitamenteVARCHAR
("se encaixa perfeitamente" = não se transforma em "?") E, de alguma forma, como por mágica, o aplicativo cresceu e agora existem milhões de registros em pelo menos um desses campos em que a maioria das linhas é ASCII padrão, mas algumas contêm caracteres Unicode, portanto, você deve mantê- lasNVARCHAR
, considere o seguinte:Se você estiver usando o SQL Server 2008 - 2016 RTM e estiver no Enterprise Edition, OU se estiver usando o SQL Server 2016 SP1 (que disponibilizou a compactação de dados em todas as edições) ou mais recente, poderá habilitar a compactação de dados . A compactação de dados pode (mas não "sempre") compactar dados
NCHAR
eNVARCHAR
campos Unicode . Os fatores determinantes são:NCHAR(1 - 4000)
eNVARCHAR(1 - 4000)
use o Esquema de compactação padrão para Unicode , mas apenas iniciando no SQL Server 2008 R2 E somente para dados IN ROW, não SOB FLUXO! Parece ser melhor que o algoritmo de compactação ROW / PAGE comum.NVARCHAR(MAX)
eXML
(e acho que tambémVARBINARY(MAX)
,TEXT
eNTEXT
) dados que estão IN ROW (não fora da linha nas páginas LOB ou OVERFLOW) podem pelo menos ser compactados em PAGE, mas não compactados em ROW. Obviamente, a compactação PAGE depende do tamanho do valor em linha: testei com VARCHAR (MAX) e vi que as linhas de 6000 caracteres / byte não seriam compactadas, mas sim as linhas de 4000 caracteres / byte.Se você estiver usando o SQL Server 2005 ou 2008 - 2016 RTM e não no Enterprise Edition, poderá ter dois campos: um
VARCHAR
e umNVARCHAR
. Por exemplo, digamos que você esteja armazenando URLs que são na sua maioria caracteres ASCII básicos (valores de 0 a 127) e, portanto, se encaixamVARCHAR
, mas às vezes têm caracteres Unicode. Seu esquema pode incluir os seguintes 3 campos:Neste modelo, você seleciona apenas a partir da
[URL]
coluna computada. Para inserir e atualizar, você determina qual campo usar, verificando se a conversão altera o valor recebido, que deve ser doNVARCHAR
tipo:Você pode GZIP inserir valores
VARBINARY(MAX)
e descompactar na saída:COMPRESS
eDECOMPRESS
funções, que também são GZip.Se você estiver usando o SQL Server 2017 ou mais recente, poderá transformar a tabela em um Índice de armazenamento de colunas em cluster.
Embora essa ainda não seja uma opção viável, o SQL Server 2019 apresenta suporte nativo para UTF-8 em
VARCHAR
/CHAR
tipos de dados. Atualmente, existem muitos bugs com ele para serem usados, mas se forem corrigidos, essa é uma opção para alguns cenários. Consulte a minha publicação, " Suporte nativo a UTF-8 no SQL Server 2019: Salvador ou Falso Profeta? ", Para uma análise detalhada desse novo recurso.fonte
Para o seu aplicativo, o nvarchar é bom porque o tamanho do banco de dados é pequeno. Dizer "sempre use nvarchar" é uma grande simplificação. Se você não precisar armazenar coisas como Kanji ou outros personagens malucos, use VARCHAR, ele utilizará muito menos espaço. Meu antecessor no meu trabalho atual projetou algo usando o NVARCHAR quando não era necessário. Recentemente, nós o mudamos para VARCHAR e salvamos 15 GB apenas nessa tabela (ela foi altamente gravada). Além disso, se você tiver um índice nessa tabela e desejar incluir essa coluna ou criar um índice composto, acabou de aumentar o tamanho do arquivo de índice.
Apenas seja atencioso em sua decisão; no desenvolvimento de SQL e nas definições de dados, raramente parece haver uma "resposta padrão" (além de evitar cursores a todo custo, é claro).
fonte
Como seu aplicativo é pequeno, não há essencialmente um aumento considerável de custo no uso de nvarchar sobre varchar, e você economiza dores de cabeça em potencial no caminho, se precisar armazenar dados unicode.
fonte
De um modo geral; Comece com o tipo de dados mais caro que tenha menos restrições. Coloque em produção . Se o desempenho começar a ser um problema, descubra o que realmente está sendo armazenado nessas
nvarchar
colunas. Existe algum personagem que não se encaixevarchar
? Caso contrário, mude para varchar. Não tente pré-otimizar antes de saber onde está a dor. Meu palpite é que a escolha entre nvarchar / varchar não é o que desacelerará seu aplicativo em um futuro previsível. Haverá outras partes do aplicativo em que o ajuste de desempenho fornecerá muito mais dinheiro para o dinheiro .fonte
Nos últimos anos, todos os nossos projetos usaram o NVARCHAR para tudo, pois todos eles são multilíngues. Os dados importados de fontes externas (por exemplo, um arquivo ASCII, etc.) são convertidos para Unicode antes de serem inseridos no banco de dados.
Ainda não encontrei problemas relacionados ao desempenho dos índices maiores, etc. Os índices usam mais memória, mas a memória é barata.
Se você usa procedimentos armazenados ou constrói SQL rapidamente, assegure-se de que todas as constantes de sequência sejam prefixadas com N (por exemplo, SET @foo = N'Hello world. ';) Para que a constante também seja Unicode. Isso evita qualquer conversão de tipo de string em tempo de execução.
YMMV.
fonte
Eu posso falar por experiência própria, cuidado com isso
nvarchar
. A menos que seja absolutamente necessário, esse tipo de campo de dados destrói o desempenho em um banco de dados maior. Eu herdei um banco de dados que estava prejudicando em termos de desempenho e espaço. Conseguimos reduzir em 70% um banco de dados de 30 GB! Houve algumas outras modificações feitas para ajudar no desempenho, mas tenho certeza de que elas tambémvarchar
ajudaram significativamente. Se seu banco de dados tem o potencial de aumentar as tabelas para mais de um milhão de registros, fique longenvarchar
a todo custo.fonte
Lido com essa questão no trabalho com frequência:
Feeds FTP de inventário e preços - descrições de itens e outros textos estavam em nvarchar quando varchar funcionou bem. Convertê-los para varchar reduziu o tamanho do arquivo quase pela metade e realmente ajudou nos envios.
O cenário acima funcionou bem até que alguém colocou um caractere especial na descrição do item (talvez marca comercial, não lembre)
Eu ainda não uso o nvarchar todas as vezes sobre o varchar. Se houver alguma dúvida ou potencial para caracteres especiais, eu uso o nvarchar. Acho que uso varchar principalmente quando estou no controle de 100% do que está preenchendo o campo.
fonte
Por que, em toda essa discussão, não houve menção ao UTF-8? Ser capaz de armazenar a extensão unicode completa de caracteres não significa que é preciso sempre alocar dois bytes por caractere (ou "ponto de código" para usar o termo UNICODE). Todo o ASCII é UTF-8. O SQL Server verifica nos campos VARCHAR () que o texto é estrito ASCII (isto é, bit de byte superior zero)? Eu espero que não.
Se você deseja armazenar unicode e compatibilidade com aplicativos antigos, apenas ASCII, acho que usar VARCHAR () e UTF-8 seria a mágica: ele só usa mais espaço quando necessário.
Para aqueles que não conhecem o UTF-8, recomendo uma cartilha .
fonte
N
exemplo, tipos XML e prefixados). Você não tem a opção de usar UTF-8. Além disso, as codificações Unicode (UTF-8, UCS-2 / UTF-16 e UTF-32) não podem ser aplicadas aos campos VARCHAR.Haverá casos excepcionais em que você desejará restringir deliberadamente o tipo de dados para garantir que ele não contenha caracteres de um determinado conjunto. Por exemplo, eu tive um cenário em que precisava armazenar o nome de domínio em um banco de dados. A internacionalização para nomes de domínio não era confiável no momento; portanto, era melhor restringir a entrada no nível base e ajudar a evitar possíveis problemas.
fonte
Se você estiver usando
NVARCHAR
apenas porque um procedimento armazenado do sistema exige isso, a ocorrência mais frequente sendo inexplicavelmentesp_executesql
e seu SQL dinâmico for muito longo, seria melhor do ponto de vista do desempenho fazer todas as manipulações de string (concatenação, substituição etc.) eVARCHAR
depois converter o resultado finalNVARCHAR
e alimentá-lo no parâmetro proc. Então não, nem sempre useNVARCHAR
!fonte