Existem desvantagens em usar sempre o nvarchar (MAX)?

342

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)

stucampbell
fonte
11
Apenas não entendo por que você deseja permitir que alguém digite um nome com mais de 8000 caracteres.
DForck42
2
A mesma lógica pode ser aplicada às linguagens de programação. Por que não voltar à antiga variante VB6 para todos os nossos dados? Não acho que ter freios e contrapesos em mais de um lugar seja necessariamente ruim.
Matt Spradley
11
Verifique isso: stackoverflow.com/questions/2009694/…
Akira Yamamoto
10
Sua atualização deve ser sua própria resposta a esta pergunta.
Johann
a resposta em questão foi movida para a resposta adequada, visto que o autor original não o fez. stackoverflow.com/a/35177895/10245 I figura 7 anos é tempo suficiente :-)
Tim Abell

Respostas:

153

A mesma pergunta foi feita nos fóruns do MSDN:

Da postagem original (muito mais informações lá):

Quando você armazena dados em uma coluna VARCHAR (N), os valores são fisicamente armazenados da mesma maneira. Mas quando você o armazena em uma coluna VARCHAR (MAX), atrás da tela, os dados são tratados como um valor TEXT. Portanto, é necessário algum processamento adicional ao lidar com um valor VARCHAR (MAX). (apenas se o tamanho exceder 8000)

VARCHAR (MAX) ou NVARCHAR (MAX) é considerado como um 'tipo de valor grande'. Tipos de valores grandes geralmente são armazenados 'fora da linha'. Isso significa que a linha de dados terá um ponteiro para outro local onde o 'valor grande' é armazenado ...

David Kreps
fonte
2
Então, deveria ser a pergunta, existe alguma diferença entre usar N / VARCHAR (MAX) e N / TEXT?
unsliced
18
Se bem me lembro, eles não são armazenados fora da linha apenas se o tamanho exceder 8k?
Sam Schutte
79
Eu li a resposta como "não, não há desvantagem em usar 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 querem N/VARCHAR(MAX)em vez de N/VARCHAR(1-8000)...
Kent Boogaart
11
Link morto acima - o link de trabalho para a pergunta no MSDN é social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd
68
Infelizmente, esta resposta tem vários problemas. Faz com que o limite de 8k pareça um número mágico, não é verdade, o valor é empurrado para fora da linha com base em vários fatores, incluindo 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
Remus Rusanu
50

É 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

alexmac
fonte
4
+1 Para as implicações de integração e segurança. Esse é um ângulo original a ser considerado quando a maioria das outras respostas fala sobre desempenho. Relacionadas às implicações de integração, quaisquer ferramentas (como redatores de relatórios ou designers de formulários) que usam metadados para fornecer tamanhos de controle padrão razoáveis ​​exigiriam muito mais trabalho para usar se todas as colunas fossem varchar(max).
Desiludido
A integração por banco de dados é a coisa mais ridícula que eu sei. Se é apenas uma importação feita uma vez que você pode verificar os dados antes pela função LEN.
Maxim
30

Com base no link fornecido na resposta aceita, parece que:

  1. 100 caracteres armazenados em um nvarchar(MAX)campo serão armazenados de maneira diferente de 100 caracteres em um nvarchar(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á.

  2. 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...

  1. Você não pode criar um índice em uma 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).

Tim Abell
fonte
11
fyi esta era uma edição adicionado à pergunta inicial que deveria ter sido publicado como uma resposta
Tim Abell
11
Obrigado, para mim, esta é a resposta final. Eu me perguntei o mesmo - por que não usar nvarchar(max)o tempo todo - como stringem c #? - mas o ponto 3) (a questão do índice) está dando a resposta.
SQL Police
11
Adicionada uma edição. Como uma espécie de "comprimento da corda universal", você poderia sempre usarnvarchar(4000)
Polícia SQL
@SQLGeorge Veja esta excelente resposta de Martin Smith sobre o impacto na consulta de desempenho de colunas declarantes mais amplas do que jamais serão
billinkc
@ Billinkc Obrigado, esse é um ótimo artigo. OK, então o tamanho realmente afeta a performance. Vou editar a resposta novamente.
SQL Police
28

À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.

Bill Karwin
fonte
9
Eu concordo com isso e com alguns dos outros comentários, mas continuo afirmando que essa é a responsabilidade do nível de negócios. No momento em que atinge o nível do banco de dados, ele deve fazer uma saudação e armazenar o valor, por mais ridículo que seja. Acho que o que realmente está em jogo aqui é que penso que 90% das vezes em que um desenvolvedor especifica varchar (255), sua intenção não é realmente 255 caracteres, mas algum valor de comprimento intermediário não especificado. E, considerando a troca entre valores irracionalmente grandes em meu banco de dados e exceções imprevistas, aceitarei os valores grandes.
22320 Chris B. Behrens
4
Se eles estão especificando VARCHAR (255) para indicar um comprimento desconhecido, então a culpa é deles por não pesquisar adequadamente o que estão projetando. A solução é que o desenvolvedor faça seu trabalho, não que o banco de dados permita valores irracionais.
Tom H
10
não é útil para o autor. ele excluiu explicitamente esta pergunta à qual você respondeu.
usr
6
@ Chris B Behrens: eu discordo; o esquema do banco de dados faz parte da lógica de negócios. A escolha de tabelas, relações, campos e tipos de dados é toda lógica de negócios - e vale a pena usar o RDBMS para impor as regras dessa lógica de negócios. Por um motivo, é muito raro que haja apenas uma camada de aplicativo acessando o banco de dados; por exemplo, você pode ter ferramentas de importação e extração de dados que ignoram a camada principal de negócios, o que significa que você realmente precisa do banco de dados para impor as regras.
precisa saber é o seguinte
11
Se você não precisa ou realmente deseja que longas seqüências de caracteres sejam armazenadas, é melhor reforçar os dados. Por exemplo, ao armazenar um campo PostCode, você deixaria alguém digitar centenas ou milhares de caracteres quando deveria ter no máximo 10 digamos. - o tamanho máximo deve ser validado em todos os níveis, cliente, nível de negócios E banco de dados. Se você estiver usando uma abordagem Model First, como C # e Entity Framework, poderá definir o tamanho máximo no modelo e aplicá-lo ao banco de dados, à lógica de negócios e à validação do cliente (com os gostos da validação de jquery). Só use nvarchar (max) se é realmente necessário
Peter Kerr
21

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.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
QMaster
fonte
4
Isso é interessante. Na minha caixa, parece que o MAX é 4x mais lento.
Stucampbell
4
Novos resultados no SQL Server 2012: 10 é duas vezes mais lento que 4k e MAX é 5,5 vezes mais lento que 4k.
22416
11
A maior parte do tempo é a conversão implícita de varchar para nvarchar (max). Experimente este: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @StartTime DATETIME; SELECT @startTime = GETDATE (); SELECT TOP 1000000 \ @SomeString = \ @abc FROM master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Duração = DATEDIFF (ms, \ @ StartTime, GETDATE ()); Teve que inserir \ antes das variáveis ​​para publicá-lo.
Kvasi
4
SQL Server 2014 no SSD: 150, 156, 716 (10, 4000, MAX).
Maxim
2
Obrigado por adicionar alguns números reais a esta discussão. Muitas vezes esquecemos que a construção de um caso de teste é a maneira mais rápida de obter informações.
22816 David C #
13

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.

Alex
fonte
8

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.

Nick Kavadias
fonte
11
Essa mesma restrição está em vigor para o tipo de campo TEXT, portanto, você ainda deve usar VARCHAR (MAX) em vez de TEXT.
Will Shaver
não foi possível reconstruir nosso índice de cluster devido a isso. custou-nos muito espaço em disco até que pudéssemos extrair a coluna em sua própria tabela (não podíamos dar ao luxo de bloquear a tabela para superiores ao ou 7 segundos)
Choco Smith
4

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.

mattruma
fonte
2
Então, por que não desenvolver apenas no menor denominador comum?
binki
4

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:

Use varchar quando os tamanhos das entradas de dados da coluna variarem consideravelmente. Use varchar (max) quando os tamanhos das entradas de dados da coluna variarem consideravelmente e o tamanho puder exceder 8.000 bytes.

uma discussão interessante sobre o assunto aqui .

RichardOD
fonte
2
Para coisas como números de telefone, seria muito mais agradável usar um campo char em vez de varchar. Desde que você mantenha um padrão em seu armazenamento e não precise se preocupar com números de telefone de diferentes países, nunca precisará de um campo variável para algo como um número de telefone (10 sem formatação) ou código postal (5 ou 9-10 se você adicionar os últimos quatro dígitos), etc.
TheTXI
Eu estava me referindo a números de telefone que podem variar em tamanho. Talvez eu devesse colocar isso na resposta. Qualquer coisa com comprimento fixo eu usaria um campo char.
RichardOD
Ou talvez eu devesse ter dito no meu comentário nchar ou char. :-)
RichardOD
2
O número de caracteres em um número de telefone é praticamente um requisito comercial. Se você fosse solicitado a armazenar o código padrão internacional junto com o número, ele poderia ser maior que 10. Ou uma parte do mundo pode ter mais de 10 dígitos para um número de telefone. Imagine o caso da transição de IPV4 para IPV6. Ninguém teria argumentado que precisávamos de mais de 12 dígitos nos bons e velhos dias do IPV4. Pode não ser bom se o IPV6 se tornar predominante. Esta é novamente uma alteração da regra de negócios ao longo de um período de tempo. Como é dito, a mudança é a única coisa constante que podemos esperar :)
pencilslate
2
Tenha cuidado ao supor que você sabe quantos caracteres podem estar em um campo de número de telefone ou que tipo de caracteres eles serão. A menos que o sistema use esses dados para realmente discar (nesse caso, você deve ser rigoroso quanto aos formatos), o usuário pode legitimamente colocar seqüências longas inesperadamente longas, por exemplo, "0123 456 78910 solicita a recepção pelo ramal 45 e depois transfere para James".
precisa saber é o seguinte
4

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.

Tom H
fonte
6
Na IMO, as limitações de comprimento de dados são baseadas exclusivamente nas regras de negócios, que podem mudar ao longo de um período de tempo, à medida que o aplicativo cresce. Alterar regras de negócios na lógica de negócios é mais fácil do que no nível de banco de dados. Portanto, acho que o banco de dados deve ser flexível o suficiente e não deve estar vinculado a regras de negócios, como o comprimento máximo permitido do primeiro nome, que depende muito da parte do mundo em que o usuário mora.
pencilslate
3

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.

TheTXI
fonte
Eu acho que a suposição tácita da parte do OP é que ele está lidando inteiramente com instâncias de mais de 2005 e que seus aplicativos não precisam funcionar nas versões 2000 (ou, ack, inferiores). Eu concordo totalmente com você, se houver necessidade de suportar as versões mais antigas!
John Rudy
John Rudy: Eu imagino que seja esse o caso, só sei que me deparei com esses obstáculos quando não achei que iria.
TheTXI 08/06/09
Na verdade, esse é um problema predominante ainda com coisas modernas devido ao SQL CE 4, que não suporta tipos de coluna MAX, portanto a interoperabilidade é um aborrecimento.
JohnC
3

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.

Harry Cooper
fonte
2

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.

WWC
fonte
1

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.

Cade Roux
fonte
1

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

Tony
fonte
1

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.

Matt Spradley
fonte
1

Meus testes mostraram que existem diferenças ao selecionar.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;
Kvasi
fonte
0

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'.

orip
fonte
11
É como argumentar que você não deve ter restrições de verificação para garantir que a idade de uma pessoa não seja um número negativo.
Jonathan Allen
Vejo uma diferença entre correção de dados e otimização de desempenho.
orip 15/02
0

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

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Ou isto?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]
Carlos Martini
fonte
3
Eu preferiria a lógica comercial dizendo que o nome da empresa pode ter no máximo 50 caracteres em vez de confiar em uma tabela de banco de dados para essas informações.
Khan
Eu concordo com Jeff. Não acho que a loja de persistência seja o lugar certo para definir suas regras de negócios. E em uma arquitetura em camadas, sua interface do usuário nem saberia sobre a camada de persistência.
Stucampbell
A menos que você esteja usando um valor restrito a um tamanho específico, por exemplo, código ISO para o país.
28412 Ben
2
O que isso tem a ver com uma definição de tabela? Você ainda pode ter lógica de negócios. Penso que o seu argumento não faz sentido em relação a como uma mesa é projetada. Se você ainda deseja criar algum tipo de definição em sua camada de negócios, que assim seja. Embora o que faria mais sentido, está usando um proc armazenado de qualquer maneira na camada de negócios; não é uma tabela def ??
carlos martini
11
Parece impopular, mas eu concordo com o Carlos, se o banco de dados definir um tamanho máximo, você poderá se sentir confortável em todas as camadas que você criar sobre o que provavelmente terá que lidar. Isso é particularmente importante se você tiver vários sistemas gravando no seu banco de dados.
Tim Abell 03/02
0

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

tsundoku
fonte
0

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.

Stephen Whipp
fonte
-1

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.

Dan Goldstein
fonte
5
-1. Uma cadeia de comprimento 100 armazenada em uma nvarchar(max)coluna não ocupa mais espaço em disco do que se estivesse em uma nvarchar(100)coluna.
Martin Smith
O que você está descrevendo está correto se o tamanho dos dados armazenados for maior, mas essa pergunta é sobre se o tipo de dados tem implicações no desempenho ou outras considerações.
-2

Isso tornará o design da tela mais difícil, pois você não poderá mais prever a largura dos seus controles.

pappes
fonte