Estou tentando colocar em uma escala atributos redundantes e ganho de desempenho. Embora armazenar informações redundantes cause muitas anomalias, estou focando apenas no tamanho de um atributo redundante versus armazenar um ponteiro (ou referência) para outra tupla em uma tabela diferente.
Então, qual é o tamanho do ponteiro para uma tupla nos sistemas InnoDB Mysql? Descobri que MyISAM usa 6 bytes. É o mesmo para o InnoDB? Para referência, 6 bytes tornam o armazenamento de 3 SMALLINTs (2 bytes cada) em uma tabela separada inútil em termos de armazenamento. Talvez uma pergunta equivalente seria: qual é o tamanho de um endereço de registro?
O padrão MyISAM é de 6 bytes para um ponteiro de dados em um índice. E o padrão é 5 bytes para ponteiros de índice. O "6" ao qual você está se referindo é um deslocamento de byte do arquivo .MYI para o arquivo .MYD. Isso não é necessariamente relevante para o resto da sua pergunta.
O InnoDB é muito mais complexo. Ele não usa ponteiros, apenas colunas.
Os dados são armazenados em um BTree que é ordenado pelo
PRIMARY KEY
. (Na verdade, um B + Árvore.)Um índice secundário é armazenado em um BTree separado que possui o PK em cada registro de nó.
FKs são simplesmente as colunas indicadas e são usadas para fazer uma pesquisa em um índice adequado na outra tabela.
leva 1 byte, mais alguma sobrecarga
Este último índice secundário leva até 3*(2+255)*4+? bytes --
Voltar para "ponteiros". Existem alguns "indicadores" em níveis mais baixos:
TEXT
ouBLOB
.Como regra prática, uma tabela InnoDB ocupa de 2 a 3 vezes o espaço em disco que a tabela MyISAM equivalente.
TINYINT UNSIGNED
suficiente (até 255 itens na outra tabela), pense nisso como 1 byte em cada tabela, mais 1 byte para cada chave secundária na tabela de destino.INT
é frequentemente usado (com um limite geralmente mais do que adequado de 2 bilhões), pense nisso como 4 bytes cada.Talvez uma questão mais importante seja ter um
AUTO_INCREMENT
id 'substituto' ( ) em uma tabela. Conte o número de referências nesta tabela e de outras tabelas para avaliar seu volume. E use o menor sabor doINT
que será seguro.Isso traz "queima" de ids. Em quase todos os casos,
INSERT
(e suas variantes) primeiro alocará os ids auto_inc que podem ser necessários. Se não usar todos eles (por exemplo, paraINSERT IGNORE
), os ids são perdidos (queimados). Isso pode levar ao uso, digamos,TINYINT
muito mais rápido do que o previsto. Para normalização em massa, forneço esta técnica: http://mysql.rjweb.org/doc.php/staging_table#normalization