No SQL Server 2005, existem desvantagens em tornar todos os campos de caracteres nvarchar (MAX) em vez de especificar um comprimento explicitamente, por exemplo, nvarchar (255)? (Além do óbvio, você não pode limitar o comprimento do campo no nível do banco de dados)
sql
sql-server
sql-server-2005
stucampbell
fonte
fonte
Respostas:
A mesma pergunta foi feita nos fóruns do MSDN:
Da postagem original (muito mais informações lá):
fonte
N/VARCHAR(MAX)
" porque há processamento adicional "somente se o tamanho exceder 8000". Assim, você incorre no custo somente quando necessário e seu banco de dados é menos restritivo . Estou lendo isso errado? Parece que você quase sempre queremN/VARCHAR(MAX)
em vez deN/VARCHAR(1-8000)
...sp_tableoptions
: msdn.microsoft.com/en-us/library/ms173530.aspx . Os tipos VARCHAR (255) também podem ser empurrados para fora da linha, a 'sobrecarga' mencionada pode ser exatamente a mesma para MAX e 255. Ele compara os tipos MAX com os tipos TEXT, quando eles são distintos como são obtidos (API completamente diferente para manipular, armazenamento diferente etc). Ele não menciona as diferenças reais: sem índice, sem operações on-line nos tipos MAXÉ uma pergunta justa e ele afirmou além do óbvio…
As desvantagens podem incluir:
Implicações de desempenho O otimizador de consultas usa o tamanho do campo para determinar o plano de execução mais eficaz
"1. A alocação de espaço em extensões e páginas do banco de dados é flexível. Assim, ao adicionar informações ao campo usando a atualização, seu banco de dados precisaria criar um ponteiro se os novos dados fossem mais longos que os inseridos anteriormente. Isso os arquivos do banco de dados tornar-se fragmentado = desempenho inferior em quase tudo, do índice à exclusão, atualização e inserções. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx
Implicações de integração - difícil para outros sistemas saberem se integrar ao seu banco de dados Crescimento imprevisível de dados Possíveis problemas de segurança, por exemplo, você pode travar um sistema ocupando todo o espaço em disco
Há um bom artigo aqui: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
fonte
varchar(max)
.Com base no link fornecido na resposta aceita, parece que:
100 caracteres armazenados em um
nvarchar(MAX)
campo serão armazenados de maneira diferente de 100 caracteres em umnvarchar(100)
campo - os dados serão armazenados em linha e você não terá a sobrecarga de ler e gravar dados 'fora de linha'. Portanto, não se preocupe lá.Se o tamanho for maior que 4000, os dados serão armazenados 'fora da linha' automaticamente, o que você deseja. Portanto, não se preocupe lá também.
Contudo...
nvarchar(MAX)
coluna. Você pode usar a indexação de texto completo, mas não pode criar um índice na coluna para melhorar o desempenho da consulta. Para mim, isso fecha o acordo ... é uma desvantagem definitiva sempre usar o nvarchar (MAX).Conclusão:
Se você deseja um tipo de "comprimento universal de seqüência de caracteres" em todo o banco de dados, que possa ser indexado e que não desperdice espaço e tempo de acesso, use-o
nvarchar(4000)
.fonte
nvarchar(max)
o tempo todo - comostring
em c #? - mas o ponto 3) (a questão do índice) está dando a resposta.nvarchar(4000)
Às vezes, você deseja que o tipo de dados imponha algum sentido aos dados contidos nele.
Digamos, por exemplo, que você tenha uma coluna que realmente não deve ter mais que, digamos, 20 caracteres. Se você definir essa coluna como VARCHAR (MAX), algum aplicativo não autorizado poderá inserir uma cadeia longa nela e você nunca saberia ou teria alguma maneira de evitá-la.
Na próxima vez que seu aplicativo usar essa cadeia, supondo que o comprimento da cadeia seja modesto e razoável para o domínio que representa, você experimentará um resultado imprevisível e confuso.
fonte
Verifiquei alguns artigos e encontrei um script de teste útil a partir disso: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Em seguida, mudei para comparar entre NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX ) e não encontro diferença de velocidade ao usar números especificados, mas ao usar MAX. Você pode testar sozinho. Espero que esta ajuda.
fonte
Pense nisso como apenas mais um nível de segurança. Você pode projetar sua tabela sem relacionamentos de chave estrangeira - perfeitamente válidos - e garantir a existência de entidades associadas inteiramente na camada de negócios. No entanto, chaves estrangeiras são consideradas boas práticas de design porque adicionam outro nível de restrição, caso algo atrapalhe a camada de negócios. O mesmo vale para a limitação do tamanho do campo e para não usar o varchar MAX.
fonte
Um motivo para NÃO usar campos máximos ou de texto é que você não pode executar recriações de índice online, ou seja, REBUILD WITH ONLINE = ON, mesmo no SQL Server Enterprise Edition.
fonte
O único problema que encontrei foi que desenvolvemos nossos aplicativos no SQL Server 2005 e, em uma instância, precisamos oferecer suporte ao SQL Server 2000. Acabei de aprender, da maneira mais difícil que o SQL Server 2000 não gosta da opção MAX para varchar ou nvarchar.
fonte
Má idéia quando você sabe que o campo estará em um intervalo definido - de 5 a 10 caracteres, por exemplo. Acho que só usaria max se não tivesse certeza de qual seria o comprimento. Por exemplo, um número de telefone nunca seria superior a um determinado número de caracteres.
Você pode dizer honestamente que não tem certeza sobre os requisitos de comprimento aproximado para todos os campos da sua tabela?
No entanto, entendo seu ponto de vista - há alguns campos que eu consideraria usar varchar (max).
Curiosamente, os documentos do MSDN resumem muito bem:
Há uma discussão interessante sobre o assunto aqui .
fonte
O trabalho do banco de dados é armazenar dados para que possam ser usados pela empresa. Parte da utilidade desses dados é garantir que sejam significativos. Permitir que alguém digite um número ilimitado de caracteres para o primeiro nome não garante dados significativos.
Criar essas restrições na camada de negócios é uma boa idéia, mas isso não garante que o banco de dados permaneça intacto. A única maneira de garantir que as regras de dados não sejam violadas é aplicá-las no nível mais baixo possível no banco de dados.
fonte
Um problema é que, se você estiver trabalhando com várias versões do SQL Server, o MAX nem sempre funcionará. Portanto, se você estiver trabalhando com bancos de dados herdados ou qualquer outra situação que envolva várias versões, é melhor ter muito cuidado.
fonte
Como foi apontado acima, é principalmente uma troca entre armazenamento e desempenho. Pelo menos na maioria dos casos.
No entanto, há pelo menos um outro fator que deve ser considerado ao escolher n / varchar (Max) em vez de n / varchar (n). Os dados serão indexados (como, por exemplo, um sobrenome)? Como a definição MAX é considerada um LOB, qualquer coisa definida como MAX não está disponível para indexação. e sem um índice, qualquer pesquisa envolvendo os dados como predicado em uma cláusula WHERE será forçada a uma varredura de tabela completa, que é o pior desempenho possível para pesquisas de dados.
fonte
1) O servidor SQL precisará utilizar mais recursos (memória alocada e tempo da CPU) ao lidar com nvarchar (max) vs nvarchar (n) em que n é um número específico para o campo.
2) O que isso significa em relação ao desempenho?
No SQL Server 2005, consultei 13.000 linhas de dados de uma tabela com 15 colunas nvarchar (max). Cronometrei as consultas repetidamente e depois alterei as colunas para nvarchar (255) ou menos.
A média das consultas anteriores à otimização foi de 2,0858 segundos. As consultas após a alteração retornaram em média 1,90 segundos. Foram cerca de 184 milissegundos de melhoria na consulta básica select *. Isso é uma melhoria de 8,8%.
3) Meus resultados estão de acordo com alguns outros artigos que indicaram que houve uma diferença de desempenho. Dependendo do banco de dados e da consulta, a porcentagem de melhoria pode variar. Se você não tiver muitos usuários simultâneos ou muitos registros, a diferença de desempenho não será um problema para você. No entanto, a diferença de desempenho aumentará à medida que mais registros e usuários simultâneos aumentarem.
fonte
Eu tinha um udf que preenchia as cordas e colocava a saída em varchar (max). Se isso foi usado diretamente em vez de converter novamente para o tamanho apropriado para a coluna ser ajustada, o desempenho foi muito baixo. Acabei colocando o udf em um tamanho arbitrário com uma grande nota em vez de confiar em todos os chamadores do udf para refazer a conversão da string para um tamanho menor.
fonte
suporte de sistema legado. Se você possui um sistema que está usando os dados e espera-se que ele tenha um determinado comprimento, o banco de dados é um bom local para aplicá-lo. Isso não é ideal, mas os sistemas legados às vezes não são ideais. = P
fonte
Se todos os dados em uma linha (para todas as colunas) nunca tiverem razoavelmente 8000 caracteres ou menos, o design na camada de dados deverá impor isso.
O mecanismo de banco de dados é muito mais eficiente, mantendo tudo fora do armazenamento de blob. Quanto menor você pode restringir uma linha, melhor. Quanto mais linhas você puder empilhar em uma página, melhor. O banco de dados tem um desempenho melhor quando precisa acessar menos páginas.
fonte
Meus testes mostraram que existem diferenças ao selecionar.
fonte
Link interessante: Por que usar um VARCHAR quando você pode usar TEXTO?
É sobre o PostgreSQL e o MySQL, então a análise de desempenho é diferente, mas a lógica da "explicitação" ainda é válida: por que se forçar a se preocupar sempre com algo relevante em uma pequena porcentagem do tempo? Se você salvou um endereço de email em uma variável, usaria uma 'sequência' e não uma 'sequência limitada a 80 caracteres'.
fonte
A principal desvantagem que posso ver é que digamos que você tenha isso:
Qual deles fornece mais informações sobre os dados necessários para a interface do usuário?
este
Ou isto?
fonte
Uma desvantagem é que você projetará em torno de uma variável imprevisível e provavelmente ignorará, em vez de tirar proveito da estrutura de dados interna do SQL Server, composta progressivamente de Linhas, páginas e extensões.
O que me faz pensar sobre o alinhamento da estrutura de dados em C, e que estar ciente do alinhamento é geralmente considerado uma coisa boa (TM). Idéia semelhante, contexto diferente.
Página MSDN para páginas e extensões
Página MSDN para dados de estouro de linha
fonte
primeiro pensei sobre isso, mas depois pensei novamente. Há implicações no desempenho, mas igualmente serve como uma forma de documentação para se ter uma idéia do tamanho dos campos. E é aplicado quando esse banco de dados fica em um ecossistema maior. Na minha opinião, a chave é ser permissivo, mas apenas dentro da razão.
ok, aqui estão meus sentimentos simplesmente sobre a questão da lógica de negócios e da camada de dados. Depende, se o seu banco de dados é um recurso compartilhado entre sistemas que compartilham a lógica de negócios, é claro que parece um lugar natural para aplicar essa lógica, mas não é a MELHOR maneira de fazê-lo, a MELHOR maneira é fornecer uma API, isso permite a interação a ser testada e mantém a lógica comercial onde ela pertence, mantém os sistemas dissociados, mantém suas camadas dentro de um sistema dissociado. Se, no entanto, seu banco de dados deveria servir apenas um aplicativo, vamos pensar em AGILE, o que é verdade agora? design por enquanto. Se e quando esse acesso for necessário, forneça uma API para esses dados.
obviamente, porém, esse é apenas o ideal, se você estiver trabalhando com um sistema existente, é provável que precise fazer isso de maneira diferente, pelo menos a curto prazo.
fonte
Isso causará um problema de desempenho, embora nunca possa causar problemas reais se o banco de dados for pequeno. Cada registro ocupará mais espaço no disco rígido e o banco de dados precisará ler mais setores do disco se você estiver pesquisando vários registros ao mesmo tempo. Por exemplo, um registro pequeno pode caber 50 em um setor e um registro grande pode caber 5. Você precisaria ler 10 vezes mais dados do disco usando o registro grande.
fonte
nvarchar(max)
coluna não ocupa mais espaço em disco do que se estivesse em umanvarchar(100)
coluna.Isso tornará o design da tela mais difícil, pois você não poderá mais prever a largura dos seus controles.
fonte