103 colunas em uma só tabela do BD

Amigos experientes do GUJ, preciso da consultoria de vocês:

A situação é a seguinte: estou trabalhando com JavaFX/Netbeans/PostreSQL e criando um sistema para controlar a manutenção de máquinas. Isso significa que, para cada máquina, existirão vários relatórios de manutenção mensais. De acordo com a minha lógica, o BD fica da seguinte forma:

01 tabela para cadastro das máquinas;
01 tabela para cadastro dos relatórios (sendo esta, relacionada com a tabela de máquinas).

Até aí, tudo bem. O problema é os relatórios são do tipo check list, o que resultou em uma tabela com 103 colunas!

A pergunta é: mantenho todas essas colunas ou diminuo a quantidade para 03 colunas, sendo a primeira o ID de cada relatório, a segunda o ID da máquina e a terceira, uma coluna onde eu armazene uma string com cada um dos itens do check list, separados por vírgulas?

Minha ideia é: quando for apresentar o relatório na tela, ler essa string e, jogar os dados em seus devidos lugares, de acordo com os locais das vírgulas.

A ideia da GRANDE STRING dá certo? A performance fica boa? Podem existir problemas futuros? Isso, diminuirá o tamanho do banco de dados?

OBS: com alguns desses dados da GRANDE STRING, precisarei fazer contas simples (soma, multiplicação, etc). Também precisarei fazer consultas (SELECT) a partir deles.

OBS 2: não vi lógica possível para separar os campos do relatório em várias tabelas relacionadas.

Caso achem que essa GRANDE STRING não dá certo, teriam alguma solução melhor para diminuir a quantidade de colunas? Ou devo mantê-las?

Agradeço, antecipadamente.

Estou entendendo que cada máquina terá seu próprio checklist (com campos variando), ou é um checklist único pra todos os tipos de máquinas? Pode dar um exemplo de quais seriam essas colunas?

103 colunas parece muito, mas essa informação por si só não indica um problema. Há casos em que esse tipo de coisa pode mesmo acontecer. E não acho que o tamanho do banco vá ser afetado pela quantidade de colunas ou tamanho de algum campo. No geral, importa mais a quantidade e tipo dos registros.

Já pensou em criar uma tabela secundária em que cada registro é o valor de cada uma dessas 103 colunas? Algo como:

tabela relatorio(id_relatorio, )
tabela relatorio_item(id_relatorio_item, id_relatorio, valor);

Assim, cada relatório terá 103 registros (não colunas) na tabela relatorio_item, com a respectiva informação na coluna valor (que provavelmente será varchar, mas você pode fazer conversões para os cálculos).

Abraço.

1 curtida

Onrigado pela resposta, @TerraSkilll.

Vou te dar um exemplo real, para que você entenda melhor, a situação:

As máquinas citadas são GRUPOS GERADORES. Dessa forma, um técnico visita o cliente, mensalmente e faz todas as verificações dessa máquina, preenchendo um check list. Esse check list é PADRÃO, ou seja, todos os itens dele são repetidos a cada visita.

Dessa forma, cada máquina cadastrada tem VÁRIOS check lists, com os MESMOS ITENS ligados a ela.

Vou te dar exemplo de 05 itens dos 103:

NÍVEL DO ÓLEO OK?
FILTROS OK?
LIMPEZA OK?
TEMPERATURA OK?
PRESSÃO DO ÓLEO OK?

Cada um desses campos é do tipo VARCHAR e só precisam ter o tamanho de 5 caracteres.

Dos 103 campos, existem 05 que são do tipo INTEGER, que são aqueles que utilizarei para fazer contas.

Gostei da sua ideia de criar uma tabela secundária. Isso resolveria o problema da quantidade de colunas. Mas a pergunta mais importante é: qual das duas opções teria a melhor performance, no momento do SELECT? 103 COLUNAS ou TABELA SECUNDÁRIA (lembrando que a tabela secundária ficaria com uma quantidade imensa de registros, já que cada relatório inserido, equivaleria a 103 registros.

Opa! Informei algo errado.

“Dos 103 campos, existem 05 que são do tipo INTEGER, que são aqueles que utilizarei para fazer contas.”

Esses campos são DOUBLE.

Repensando um pouco, ter um campo string com tudo vai ser bem complicado de controlar e dar manutenção.

O ideal seria você testar ambos os casos. Sem testes, só dá pra deduzir. Mas não acho que isso seja um problema tão grande quanto você está imaginando. A não ser que você tenha uma quantidade absurda de máquinas (ex: 100 mil máquinas), não acho que desempenho vá ser um problema. Com a estrutura e os índices adequados, você vai ter consultas que demoram pouco (alguns segundos), desde que não queira selecionar todos os relatórios de todas as máquinas ao mesmo tempo.

Se entendi o cenário, uma mesma máquina passará por várias checagens ao longo do tempo, então cada checagem precisa ser registrada. Nesse caso, Note que você pode que separar o que é dado do relatório do que é tipo de checagem. Por exemplo, você pode colocar o tipo numa terceira tabela, e os itens double numa quarta, e referenciá-la nas demais. Algo como:

tabela tipo_checagem(id_tipo_checagem, descricao);
tabela relatorio(id_relatorio, data);
tabela relatorio_item(id_relatorio_item, id_relatorio, id_tipo_checagem, valor);  // valor é varchar ou int
tabela relatorio_item_double(id_relatorio_item_double, id_relatorio, id_tipo_checagem, valor); // valor é double

Note que, se o valor alterna entre dois estados (ok e não ok), você pode armazenar como char ou inteiro (0 para ok, 1 para não ok, por exemplo), o que tem um desempenho bem melhor que varchar no geral. Você pode inclusive marcar se o tipo de checagem precisa ou não de conversão (com uma coluna a mais). Acho que isso não terá desempenho ruim, e será mais fácil de dar manutenção.

Se não quiser criar uma diferenciação para os valores que são inteiro e precisa de conversão, você pode gravar como varchar e fazer as conversões conforme precisar, seja no select, seja na aplicação.

Abraço.

1 curtida

Ok.

Obrigado, @TerraSkilll.

Ajudou, bastante.

:+1::+1::+1::+1::+1::+1::+1::+1: