Estou tentando entender a melhor maneira de decidir o tamanho das colunas varchar, tanto do ponto de vista de armazenamento quanto de desempenho.
Desempenho
Da minha pesquisa, pareceesse varchar (max) só deve ser usado se você realmente precisar; isto é, se a coluna deve acomodar mais de 8000 caracteres, uma razão é a falta de indexação (embora eu seja um pouco desconfiado de indexar nos campos varchar em geral. Sou bastante novo nos princípios do banco de dados, então talvez isso seja infundado ) e compactação (mais uma preocupação de armazenamento). De fato, em geral, as pessoas parecem recomendar apenas o uso do que você precisa, ao fazer o varchar (n) .... oversizing é ruim, porque as consultas devem levar em conta o tamanho máximo possível. Mas também foi afirmado que o mecanismo usará metade do tamanho indicado como uma estimativa do tamanho real médio dos dados. Isso implica que se deve determinar, a partir dos dados, qual é o tamanho médio, dobrá-lo e usá-lo como n. Para dados com variabilidade muito baixa, mas diferente de zero, isso implica em um tamanho 2x maior do que o tamanho máximo, o que parece muito, mas talvez não seja? Insights seriam apreciados.
Armazenamento
Depois de ler sobre como o armazenamento em linha e o armazenamento fora de linha funciona, e tendo em mente que o armazenamento real é limitado a dados reais, parece-me realmente que a escolha de n tem pouca ou nenhuma influência no armazenamento (além de certificando-se de que é grande o suficiente para armazenar tudo). Mesmo usando varchar (max) não deve ter nenhum impacto no armazenamento. Em vez disso, um objetivo pode ser limitar o tamanho real de cada linha de dados a ~ 8000 bytes, se possível. Essa é uma leitura precisa das coisas?
Contexto
Alguns dados de nossos clientes flutuam um pouco, então geralmente tornamos as colunas um pouco mais amplas do que precisam, digamos 15 a 20% maiores, para essas colunas. Fiquei imaginando se havia outras considerações especiais; por exemplo, alguém com quem trabalho me disse para usar tamanhos 2 ^ n - 1 (embora eu não tenha encontrado nenhuma evidência disso ...)
Eu estou falando sobre a criação da tabela inicial. Um cliente nos dirá que eles começarão a nos enviar uma nova tabela e enviar dados de amostra (ou apenas o primeiro conjunto de dados de produção), para os quais analisamos e fazemos uma tabela para armazenar os dados. Queremos fazer a tabela do nosso lado para lidar com futuras importações e com o que está na amostra. Porém, certas linhas tendem a ficar mais longas, então as protegemos.
A questão é quanto e existem diretrizes técnicas?
fonte
Respostas:
Independentemente do tipo de dados específico, você precisa poder armazenar o que o aplicativo solicitar para ser armazenado. Você não pode especificar algo menor que o tamanho máximo do que realmente será salvo.
Você também não precisa nem deseja especificar um comprimento de coluna maior que o tamanho real máximo que será armazenado por vários motivos: consulta à alocação de memória, potencialmente preenchendo o tamanho máximo de linha e não deixando espaço para adicionar colunas o futuro etc.
É verdade que a string de comprimento variável e as colunas binárias não têm a implicação de armazenamento que os tipos de dados de comprimento fixo (string / binary / numeric / date / etc) possuem (embora algumas dessas implicações possam ser anuladas por meio de compactação de dados ou uso da
SPARSE
definição de coluna opção). No entanto, como você apontou, mesmo se não houver implicação direta de armazenamento, ainda há a implicação de desempenho de superestimar a memória necessária para consultas.Seja sensato. Use apenas o que precisar. Considerações podem ser feitas se houver uma alta probabilidade de que o comprimento da coluna precise aumentar no futuro próximo, mas lembre-se de que é mais fácil expandir o tamanho de uma coluna do que reduzir o tamanho. Sim, algum trabalho estará envolvido, mas, como esse trabalho é apenas "potencial", enquanto as implicações de desempenho do sobredimensionamento são "reais", geralmente é melhor definir colunas com base no que você realmente precisa, e não no que você talvez meio -sorta acho que você pode precisar no futuro. Muitas mudanças mencionadas nunca acontecem e, muitas vezes, as mudanças necessárias não podem ser previstas. Vá com o que você sabe.
Não sei exatamente o que você está recebendo aqui. O SQL Server limitará fisicamente você a pouco mais de 8000 bytes. Utilizando tipos LOB -
VARCHAR(MAX)
,NVARCHAR(MAX)
,VARBINARY(MAX)
,XML
, e a preteridaTEXT
,NTEXT
eIMAGE
tipos - permitir que ultrapasse o limite de tamanho de página inicial, mas que é apenas devido à colocação de um ponteiro (16 ou mais bytes, dependendo do tipo e dependendo da tamanho do valor armazenado off-line ao usar osMAX
tipos). O limite físico real da página de dados não foi alterado.Seu objetivo deve ser usar a menor quantidade de espaço físico para armazenar o que o aplicativo / empresa precisa armazenar sem interromper ou truncar, de modo que o valor incompleto perca significado ou cause problemas a jusante. Se você precisar armazenar um número de 12.000 caracteres, use
VARCHAR(MAX)
porque é isso que é necessário. Se você estiver armazenando um número de telefone ou código postal, seria imprudenteVARCHAR(100)
e irresponsávelVARCHAR(MAX)
.Todos os sistemas não têm pelo menos alguns dados que flutuam? Qualquer sistema que armazene o nome de uma pessoa se qualificaria, certo? Há uma variação bastante grande no comprimento dos nomes. E então você tem alguém como Prince e muda seu nome para um símbolo e agora você tem um problema completamente diferente que não é longo. É assim que as coisas são.
Mas, para brincar de advogado do diabo por um momento: como o valor "15-20% maior do que o necessário" não pode ser o valor realmente necessário ? Digamos que haja uma discussão sobre a adição de uma nova coluna, e alguém sugira 50 caracteres, e outra pessoa diga: "bem, 20% a mais é 60, então vamos fazer 60 porque alguém pode ter 60". Se é verdade que um cliente pode ter 60, 60 é, e sempre foi, o valor real necessário, e 50 estava errado o tempo todo.
Obviamente, ajudaria se houvesse alguma indicação quanto à fonte dos dados, porque:
VARCHAR
e receber reclamações de que está atrapalhando caracteres Unicode que agora são permitidos em nomes de domínio, é necessárioNVARCHAR
), masProductSKU
melhor que seja grande o suficiente para caber em todos dos SKUs do cliente.Você está fazendo muitas suposições aqui. Certamente, alguns campos podem ficar maiores. Mas, novamente, eles podem não. Ou, alguns podem ficar menores. Alguns podem mudar de não-Unicode para Unicode (uma vez que percebem que o mundo está ficando menor e não se pode presumir que os sobrenomes só terão caracteres básicos em inglês ASCII / EUA). Ou eles podem parar de enviar um campo. Ou eles podem adicionar um ou mais campos no futuro. Qualquer combinação disso e de outras coisas. Então, por que focar apenas nas
VARCHAR
colunas? E se eles estiverem enviando umINT
valor no momento e em um ou dois anos atingirem o valor máximo e começarem a enviar umBIGINT
? E se eles tiverem um campo "status" com valores de 0 a 5. Você apenas assumiráINT
que é "acolchoado", pois permite o crescimento, mas provavelmente deveria serTINYINT
?A única coisa que você pode prever com segurança é que tentar prever como os dados de seus clientes serão alterados estará errado com mais frequência do que o correto. E estar correto é uma questão de sorte / coincidência (se não for sorte, basta ir jogar na loteria;).
Portanto, a diretriz é:
Você já tem dados de exemplo, ótimo. Mas não esqueça que você também tem as informações de contato do seu cliente: telefone e / ou e-mail. Contate-os! Peça a eles suas especificações de dados (assim como seu sistema, os dados atualmente em seu sistema podem ter um comprimento máximo de 35, mas o sistema o definiu como
VARCHAR(50)
e o sistema aceitará esse comprimento; nesse caso, você deve usar 50) E pergunte se eles têm algum plano de curto prazo para alterar e desses tipos de dados (tipo e / ou tamanho).fonte
varchar(255)
e umvarchar(256)
para algumas outras considerações