Em geral, eu sempre uso Ints. Eu sei que, em teoria, essa não é a melhor prática, pois você deve usar o menor tipo de dados que será garantido para armazenar os dados.
Por exemplo, é melhor usar tinyint
quando você sabe que os únicos dados que você armazenará são 1, 0 ou nulo (com uma chance muito pequena de expandir isso para 2 ou 3 depois).
No entanto, a única razão que conheço para fazer isso é para fins de armazenamento - usando 1 byte em uma linha em vez de 4 bytes.
Quais são os impactos de usar tinyint
( smallint
ou mesmo bigint
) sobre apenas int
, além de economizar espaço no disco rígido?
O espaço em disco é barato... esse não é o ponto!
Pare de pensar em termos de espaço de armazenamento, pense em buffer pool e largura de banda de armazenamento . No extremo, cache da CPU e largura de banda do barramento de memória . O artigo vinculado faz parte da série que destaca problemas com a seleção de chaves clusterizadas inadequadas (INT vs GUID vs GUID Sequencial), mas destaca a diferença que os bytes podem fazer.
A mensagem principal é a questão do design. A diferença não aparecerá em um banco de dados individual em um servidor adequadamente especificado até que você atinja o território VLDB, mas se você puder economizar alguns bytes, por que não fazê-lo.
Lembro-me do ambiente descrito em uma pergunta anterior . Mais de 400 bancos de dados, variando em tamanho de 50 MB a 50 GB, por instância SQL. Limpar alguns bytes por registro, por tabela, por banco de dados nesse ambiente pode fazer uma diferença significativa.
Além das outras respostas...
As linhas e entradas de índice são armazenadas em 8k páginas. Portanto, um milhão de linhas a 3 bytes por linha não é 3 MB no disco: afeta o número de linhas por página ("densidade da página").
O mesmo se aplica a nvarchar para varchar, smalldatetime para datetime, int para tinyint etc
Editado, junho de 2013
http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx
Este artigo afirma
Portanto, a escolha do tipo de dados importa
Não é apenas o armazenamento de tabela que é considerado. Se você usa índices em que a coluna int faz parte de uma chave composta, naturalmente deseja que as páginas de índice sejam o mais completas possível, sendo isso o resultado de as entradas de índice serem as menores possíveis.
Eu definitivamente esperaria descobrir que examinar entradas de índice em páginas BTREE seria um pouco mais rápido com tipos de dados menores. No entanto, quaisquer VARCHARs envolvidos em entradas de índice compensariam (anulariam) os ganhos de desempenho do uso de TINYINT sobre INT.
Não obstante, se as entradas de índice tiverem entradas compostas e todas forem números inteiros, quanto menores forem os números inteiros, melhor e mais rápido.
Todas as coisas se tornam complexas quando os bancos de dados ficam maiores:
E que tipos de dados têm a ver com isso? TUDO. O uso de tamanhos de linha maiores do que o necessário faz com que as páginas do banco de dados sejam preenchidas antes do necessário ou até mesmo desperdiçando espaço se o tamanho da linha for tal que não seja possível gravar mais de um registro na página. O resultado é mais páginas necessárias para serem escritas e lidas, mais memória RAM é usada para armazenar em cache (registros maiores precisam de mais memória). E como seus tipos de dados são especificados maiores do que o necessário do disco, seus índices sofrerão o mesmo problema - especialmente se você agrupar essa chave primária composta de 2 colunas BIGINT, pois quaisquer outros índices criados copiarão essa chave primária implicitamente em sua definição.
Se você sabe que algumas colunas em uma tabela que terá milhões de linhas ou até mesmo uma pequena tabela que será FK'ed para vários milhões de linhas que não precisa de um inteiro de 4 bytes para armazenar seus dados, mas um de 2 bytes seria basta - use SMALLINT . Se os valores no intervalo de 0 a 255 forem suficientes, TINYINT . Uma bandeira Sim/Não? Tem BIT .
Enquanto para
tinyint
vsint
existem diferenças claras, como espaço em disco, divisões de página e tempo de manutenção, não haveria nenhuma delas paravarchar
.Então, por que não declarar todos os campos de texto como
varchar(4000)
, já que ele usará apenas o espaço necessário? Ainda mais você terá a garantia de que seus dados nunca serão truncados.A resposta é claro:
Essas mesmas razões se aplicam
tinyint
também.