Código de erro 1117 Colunas demais; Limite de colunas do MySQL na tabela


37

Eu tenho uma tabela com 1699 colunas e quando estou tentando inserir mais colunas,

Código de erro: 1117. Muitas colunas

Nesta tabela, tenho apenas 1000 linhas. Para mim, o mais importante é o número de colunas. Existem limitações na mesa? Eu quero criar 2000 colunas. Isso é possível?


22
Bom Deus, o que diabos. Isso cheira a um design de banco de dados incrivelmente ruim. Ou talvez você esteja usando a ferramenta errada para o trabalho. Talvez você deve estar olhando para normalização de dados
Zoredache

12
Gire seu monitor 90 graus. Mais seriamente, o MySQL (ou quase qualquer outro RDBMS) não foi projetado para MUITAS colunas.

11
E por que 2000 sensores devem levar a 2000 colunas? Redesenhe seu banco de dados. Crie uma tabela de sensores separada ou algo assim, mas NÃO adicione cada sensor como uma nova coluna. Isso é algo inacreditavelmente errado de se fazer.

6
Número máximo da tabela ... whoa lá! Você provavelmente precisará de apenas duas tabelas. Nem pense em criar 2000 tabelas em vez de 2000 colunas!

2
Por favor, por favor, leia sobre Normalização do Banco de Dados !

Respostas:


35

Por que você precisaria criar uma tabela com até 20 colunas, sem falar em 2000 ???

Dados concedidos e desnormalizados podem impedir que JOINs recuperem muitas colunas de dados. No entanto, se você tiver mais de 10 colunas, pare e pense no que aconteceria durante a recuperação de dados.

Se uma tabela de 2000 colunas passar por SELECT * FROM ... WHERE, você geraria tabelas temporárias grandes durante o processamento, buscando colunas desnecessárias e criando muitos cenários em que os pacotes de comunicação ( max_allowed_packet ) seriam empurrados para o limite em todas as consultas.

Nos meus primeiros dias como desenvolvedor, trabalhei em uma empresa em 1995, onde o DB2 era o principal RDBMS. A empresa tinha uma única tabela com 270 colunas, dezenas de índices e problemas de desempenho na recuperação de dados. Eles entraram em contato com a IBM e os consultores examinaram a arquitetura de seu sistema, incluindo esta tabela monolítica. A empresa foi informada "Se você não normalizar esta tabela nos próximos 2 anos, o DB2 falhará nas consultas que executam o Stage2 Processing (qualquer consulta que exija classificação em colunas não indexadas)". Isso foi dito a uma empresa multibilionária, para normalizar uma tabela de 270 colunas. Quanto mais uma tabela de 2000 colunas.

Em termos de mysql, você teria que compensar um projeto tão ruim definindo opções comparáveis ​​ao DB2 Stage2 Processing. Nesse caso, essas opções seriam

Ajustar essas configurações para compensar a presença de dezenas e muito menos centenas de colunas funciona bem se você tiver TBs de RAM.

Esse problema se multiplica geometricamente se você usar o InnoDB, pois precisará lidar com o MVCC (Multiversion Concurrency Control) tentando proteger toneladas de colunas com cada SELECT, UPDATE e DELETE através do isolamento de transações.

CONCLUSÃO

Não há substituto ou band-aid que possa compensar o mau design. Por favor, para sua sanidade no futuro, normalize essa tabela hoje !!!


1
Eu poderia imaginar como a empresa faria quando soubesse disso. Eles adicionam svn hooks ou criam "diretrizes de boas práticas de banco de dados" pedindo que os desenvolvedores não classifiquem colunas não indexadas no SQL. Em vez disso, eles fazem a classificação no aplicativo implementando seu próprio algoritmo de classificação de dados grandes.
precisa saber é o seguinte

25

Estou tendo problemas para imaginar qualquer coisa em que o modelo de dados possa conter legitimamente 2000 colunas em uma tabela normalizada corretamente.

Meu palpite é que você provavelmente está fazendo algum tipo de esquema desnormalizado de "preencher os espaços em branco", onde na verdade você está armazenando todos os tipos diferentes de dados em uma tabela e, em vez de dividir os dados em tabelas separadas e fazer relações , você tem vários campos que registram qual "tipo" de dados é armazenado em uma determinada linha e 90% dos seus campos são NULL. Mesmo assim, porém, quero chegar a 2000 colunas ... caramba.

A solução para o seu problema é repensar o seu modelo de dados. Se você está armazenando uma grande pilha de dados de chave / valor associados a um determinado registro, por que não modelá-lo dessa maneira? Algo como:

CREATE TABLE master (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields that really do relate to the
    master records on a 1-to-1 basis>
);

CREATE TABLE sensor_readings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    master_id INT NOT NULL,   -- The id of the record in the
                              -- master table this field belongs to
    sensor_id INT NOT NULL,
    value VARCHAR(255)
);

CREATE TABLE sensors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields relating to sensors>
);

Em seguida, para obter todas as entradas do sensor associadas a um determinado registro "mestre", você pode apenas SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Se você precisar obter os dados para um registro na mastertabela junto com todos os dados do sensor para esse registro, poderá usar uma associação:

SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>

E depois junte-se mais se precisar de detalhes sobre o que é cada sensor.


18

É um sistema de medição com 2000 sensores

Ignore todos os comentários gritando sobre normalização - o que você está pedindo pode ser um design de banco de dados sensato (em um mundo ideal) e perfeitamente normalizado, é muito incomum e, como indicado em outro lugar, os RDBMSs geralmente não são projetados para essas muitas colunas .

Embora você não esteja atingindo o limite rígido do MySQL , um dos outros fatores mencionados no link provavelmente está impedindo que você suba mais

Como outros sugerem, você pode solucionar essa limitação id, sensor_id, sensor_valuecriando uma tabela filho com , ou mais simplesmente, criar uma segunda tabela para conter apenas as colunas que não cabem na primeira (e usar a mesma PK)


1
Isso é verdade. Ao lidar com dados e SQL correspondente com muito cuidado, sua resposta se destaca ainda mais !!!
RolandoMySQLDBA

3
Usar uma tabela filha não é uma "solução alternativa". Ter uma coluna para cada sensor é simplesmente um projeto ruim (errado). É como ter uma coluna para cada funcionário em um sistema de RH ou uma coluna para cada fabricante de carros de um banco de dados que gerencia modelos de carros.
A_horse_with_no_name 21/07

11
@a_horse - você está fazendo suposições que duvido que sejam válidas. É bem possível que o número de sensores seja basicamente fixo, que todos sejam lidos simultaneamente e que todos retornem dados sempre. Nesse caso, uma coluna por sensor não está "errada", apenas impraticável, dadas as limitações do banco de dados. Eu gosto de supor que os questionadores não são idiotas até que se prove o contrário e a iUngi respondeu com dignidade diante de respostas muito inúteis da multidão do SF.
21311 Jack Douglas

2
@ Jack Douglas: mesmo que todas essas suas suposições fossem verdadeiras (o que eu duvido) armazenar cada valor de sensor em sua própria coluna causará problemas a longo prazo. E quanto a consultas como "qual é o valor médio dos sensores 10 a 50 e 25 a 100 entre ontem e hoje"? ou "Qual sensor teve o maior valor de leitura na última segunda-feira?". Tente escrever consultas para isso com 2000 colunas. O uso de uma tabela normalizada resolverá mais problemas a longo prazo do que a solução de 2000 colunas resolverá agora.
A_horse_with_no_name

2
Claro, se os sensores estão armazenando valores relacionados - suponho que não sejam relacionados (por exemplo, todos medem diferentes tipos de coisas, em vez de basicamente a mesma coisa em locais diferentes). Você pode duvidar disso, mas apenas o OP sabe com certeza - e isso não é impossível nas áreas médica ou científica.
21411 Jack Douglas

15

Limites de contagem de colunas do MySQL 5.0 (ênfase adicionada):

Há um limite rígido de 4096 colunas por tabela , mas o máximo efetivo pode ser menor para uma determinada tabela. O limite exato depende de vários fatores de interação.

  • Cada tabela (independentemente do mecanismo de armazenamento) tem um tamanho máximo de linha de 65.535 bytes. Os mecanismos de armazenamento podem colocar restrições adicionais nesse limite, reduzindo o tamanho máximo efetivo da linha.

    O tamanho máximo da linha restringe o número (e possivelmente o tamanho) das colunas porque o comprimento total de todas as colunas não pode exceder esse tamanho.

...

Mecanismos de armazenamento individuais podem impor restrições adicionais que limitam a contagem de colunas da tabela. Exemplos:

  • O InnoDB permite até 1000 colunas.

7

Primeiro um pouco mais de chamas, depois uma solução real ...

Eu concordo principalmente com as chamas já jogadas em você.

Não concordo com a normalização de valores-chave. As consultas acabam sendo horríveis; desempenho ainda pior.

Uma maneira 'simples' de evitar o problema imediato (limitação do número de colunas) é 'particionar verticalmente' os dados. Tenha, digamos, 5 tabelas com 400 colunas cada. Todos eles teriam a mesma chave primária, exceto que um pode ser AUTO_INCREMENT.

Talvez o melhor seja decidir sobre a dúzia de campos mais importantes e colocá-los na tabela 'principal'. Em seguida, agrupe os sensores de alguma maneira lógica e coloque-os em várias tabelas paralelas. Com o agrupamento adequado, talvez você não precise ingressar em todas as tabelas o tempo todo.

Você está indexando algum dos valores? Você precisa pesquisar neles? Provavelmente você procura em data e hora?

Se você precisar indexar muitas colunas - punt.

Se você precisar indexar alguns, coloque-os na tabela principal.

Aqui está a solução real (se aplicável) ...

Se você não precisa da vasta gama de sensores indexados, não crie colunas! Sim, você me ouviu. Em vez disso, colete-os no JSON, compacte-o, armazene-o em um campo BLOB. Você economizará muito espaço; você terá apenas uma tabela, sem problemas de limite de coluna; etc. Seu aplicativo será descompactado e, em seguida, usará o JSON como uma estrutura. Adivinha? Você pode ter estrutura - você pode agrupar os sensores em matrizes, itens de vários níveis, etc., exatamente como o seu aplicativo gostaria. Outro 'recurso' - é aberto. Se você adicionar mais sensores, não precisará ALTERAR a tabela. JSON se flexível dessa maneira.

(A compactação é opcional; se o seu conjunto de dados for grande, ele ajudará no espaço em disco e, portanto, no desempenho geral.)


Esta é a melhor resposta real. Não há problema em comentar que talvez ele deva pesquisar sem ter tantas colunas, mas que a resposta aceita seja 'não faça isso' não responde à pergunta. Mesmo que esse cara não precise realmente de muitas colunas, talvez alguém que encontre esse Q precise disso e precise de uma resposta real.
BoB3K

@ BoB3K - Meu grande parágrafo diz o que fazer , dadas as informações disponíveis sobre o problema, conforme indicado. JSONevita "muitas colunas"; A indexação de colunas selecionadas ajuda no desempenho.
Rick James

3

Eu vejo isso como um cenário possível no mundo do big data, onde você pode não estar executando o tipo tradicional de consultas * select. Lidamos com isso no mundo da modelagem preditiva no nível do cliente, onde modelamos um cliente em milhares de dimensões (todas elas com valores de 0 ou 1). Essa maneira de armazenamento facilita as atividades de criação de modelo downstream etc. quando você possui os fatores de risco na mesma linha e o sinalizador de resultado na mesma linha. Isso pode ser normalizado do ponto de vista de armazenamento com uma estrutura filha pai, mas o modelo preditivo a jusante precisará convertê-lo novamente em esquema plano. Usamos o redshift, que faz o armazenamento colunar, para que suas mais de 1000 colunas ao carregar os dados sejam realmente armazenadas em um formato colunar ...

Há um tempo e um local para este design. Absolutamente. A normalização não é a solução para todos os problemas.


Obrigado pelo comentário. Se alguém quiser fazer análises com imagens, mesmo uma pequena imagem colorida de 16x16 pixels requer 16 * 16 * 3 inteiros entre 0 e 255 (3 números para descrever a cor em um dos 16x16 pixels usando cores RGB). São 768 colunas apenas para dados, às quais seria necessário adicionar uma chave.
VictorZurkowski 13/06
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.