Temos alguns engenheiros que nivelam uma estrutura de banco de dados normalizada em uma tabela temporária com o objetivo de gerar um relatório. As colunas são especificadas como TEXT NOT NULL
(eu sei "por que eles estão fazendo isso?"; Vamos apenas assumir que estamos tratando disso).
Usamos a Comunidade RHEL5 do MySQL 5.1.48 com o plug-in 1.0.9 do InnoDB no Linux.
Ao usar o MyISAM, nunca encontramos limites de tamanho de tabela de colunas máximas ou comprimento máximo de linhas (durante a investigação, atingimos o limite máximo de colunas em 2598 (o 2599 causa o erro 1117). Com o InnoDB, estamos atingindo limites. Esses limites se manifestam ao criar o tabela (sem inserção de dados) como:
ERRO 1118 (42000) na linha 1: tamanho da linha muito grande. O tamanho máximo da linha para o tipo de tabela usado, sem contar os BLOBs, é 8126. É necessário alterar algumas colunas para TEXT ou BLOBs
Estou procurando respostas para o seguinte:
Qual é a fórmula detalhada para determinar as partículas de tamanho de linha ao usar lotes de colunas v / v / b / t? Tentei alguns formulários diferentes usando
varchar(N)
colunas (onde N é entre 1 e 512), o conjunto de caracteres UTF8 (* 3) e quantas colunas a tabela levar até a falha. Nenhum dos combos que tentei fornece valores que correspondem aos resultados reais dos testes.Que outras 'despesas gerais' devo considerar ao calcular o tamanho da linha?
Por que a mensagem de erro muda de 8126 para 65535 quando passo de criar tabelas com colunas varchar (109) para varchar (110)?
Respostas:
As respostas para suas perguntas são complexas, pois variam de acordo com o formato do arquivo InnoDB . Hoje, existem dois formatos, chamados Antelope e Barracuda.
O arquivo do espaço de tabela central (ibdata1) está sempre no formato Antelope . Se você usar arquivo por tabela, poderá fazer com que os arquivos individuais usem o formato Barracuda configurando
innodb_file_format=Barracuda
em my.cnf.Pontos básicos:
Uma página de 16 KB de dados do InnoDB deve conter pelo menos duas linhas de dados. Além disso, cada página tem um cabeçalho e um rodapé contendo somas de verificação de página e número de sequência de log e assim por diante. É aí que você obtém seu limite de pouco menos de 8 KB por linha.
Tipos de dados de tamanho fixo, como INTEGER, DATE, FLOAT, CHAR, são armazenados nesta página de dados primários e contam para o limite de tamanho da linha.
Tipos de dados de tamanho variável, como VARCHAR, TEXT, BLOB, são armazenados em páginas excedentes, para que não sejam totalmente contabilizados no limite de tamanho da linha. No Antelope, até 768 bytes dessas colunas são armazenados na página de dados primária, além de serem armazenados na página de estouro. O Barracuda suporta um formato de linha dinâmico , portanto, ele pode armazenar apenas um ponteiro de 20 bytes na página de dados primária.
Os tipos de dados de tamanho variável também são prefixados com 1 ou mais bytes para codificar o comprimento. E o formato de linha do InnoDB também possui uma variedade de deslocamentos de campo. Portanto, há uma estrutura interna mais ou menos documentada em seu wiki . [EDIT] Link morto - aqui parece melhor agora.
O Barracuda também suporta um ROW_FORMAT = COMPRESSED para obter maior eficiência de armazenamento para dados excedentes.
Também devo comentar que nunca vi uma tabela bem projetada exceder o limite de tamanho da linha. É um forte "cheiro de código" que você está violando a condição de grupos repetidos da Primeira Forma Normal.
fonte
Minha situação é um pouco diferente. Um dos elementos de dados que preciso armazenar em cada linha é potencialmente muito grande. (O campo de dados é um LONGBLOB para um documento que pode conter várias imagens incorporadas. Meu banco de dados de amostra contém documentos de 25 a 30 MB, mas esses documentos podem ser maiores em alguns casos.) Nenhuma das soluções que encontrei on-line ofereceu alívio . (O tipo de arquivo do InnoDB foi alterado para Barracuda, aumentou o tamanho do arquivo de log, defina o formato da linha como COMPRESSED.)
A única solução que encontrei que funcionou para mim foi voltar ao MySQL 5.5.x do MySQL 5.6.x.
fonte