Mantendo uma enumeração e uma tabela sincronizadas

11

Estou criando um programa que postará dados em um banco de dados e encontrei um padrão que tenho certeza de que é familiar: Uma pequena tabela com os valores fixos mais prováveis ​​(muito prováveis) que servem como enumeração. Então, suponha a seguinte tabela chamada Status:

  Status
  Id Descrição
  --------------
   0 Não processado
   1 Pendente
   2 Processado
   3 Erro

No meu programa, preciso determinar um ID de status para outra tabela ou possivelmente atualizar um registro com um novo ID de status.

Eu poderia codificar os IDs de status em uma enumeração e espero que ninguém mude o banco de dados. Ou eu poderia pré-buscar os valores com base na descrição (hardcoding assim que em vez disso).

Qual seria a abordagem correta para manter esses dois enum e table sincronizados?

MPelletier
fonte
Por que você está mantendo as coisas sincronizadas e não sincronizadas? Sincronizar (diga) é estranho!
MrFox
1
@suslik Ambos são pronunciados da mesma forma. Sincronizar e sincronizar .
MPelletier
1
Ter uma enumeração e a tabela do banco de dados é duplicação. A menos que a tabela do banco de dados seja usada por outros aplicativos, eu renunciaria à tabela e apenas usaria a enumeração. Se a tabela for usada em vários aplicativos, carregue os status do banco de dados no tempo de execução.
Peter Smith
Depende do contexto. Nesse caso, sendo valores de status do fluxo de trabalho ou da tarefa, eu preferiria mantê-los mais dinâmicos do que estáticos, pois os processos costumam mudar; e tendem a mudar de banda para agendar lançamentos de software. Por outro lado, se for um serviço estável que é improvável que novos estados sejam introduzidos ou estados existentes removidos, talvez eu seja mais obrigado a codificar a enumeração / desnormalizá-los (dependendo de como os registros serão usados ​​posteriormente).
JustinC
@PeterSmith O banco de dados não pode impor restrições se elas estiverem apenas no seu enum Java e não em uma tabela. Você vai restringir valores em seu banco de dados, não é?
David Conrad

Respostas:

5

Eu codificaria a enumeração dentro do seu programa, pois suspeito que esses status diferentes afetem a lógica do seu programa. Se você tem um novo status, como o seu programa deve reagir a esse novo status?

Como o banco de dados faz parte do seu aplicativo, acho que não faria sentido afetar um sem consultar o outro, meio que falar.

Mateus
fonte
Não se trata tanto de novos status (o que definitivamente justificaria uma modificação do banco de dados e do programa), mas dos valores de ID.
MPelletier
2
Não vejo por que você alteraria o valor do ID sem alterar seu significado. Esse tipo de enumeração não seria incrementado automaticamente, e isso é realmente apenas para facilitar a leitura das pessoas que depuram o banco de dados, pois normalmente seu aplicativo fará consultas e já saberia qual pendingseria o ID . É claro que ter uma Statustabela fornece integridade referencial, mas esse é o ponto que estou tentando fazer.
Matthew
Bem, sim, essa é a ideia. Mas se eu definir os IDs em um lugar e em outros, estou trabalhando com a suposição de que ambos estão certos. É um elo solto, não?
MPelletier
3
Fazemos essas suposições o tempo todo, se você pensar em uma definição de tabela, nosso programa assume que a definição é a mesma quando se escreve uma consulta. A Statustabela não deve ser considerada dinâmica durante o tempo de execução do aplicativo e, portanto, acho que você não deve lê-la como tal.
Matthew
8

Normalmente, eu carregaria esses dados em um cache estático (geralmente em um HashMap ou algo assim) quando o aplicativo é iniciado. Evita ter que recompilar apenas porque o enum foi modificado de alguma maneira.

FrustratedWithFormsDesigner
fonte
2

Como esses são status, eles devem ser codificados no aplicativo para garantir que nenhuma alteração no banco de dados corrompa seu programa (pelo menos não facilmente). Isso é importante porque todos os status que devem ser adicionados precisam ser codificados primeiro e não simplesmente adicionados ao banco de dados.

Você ainda deve ter esses valores de status gravados no banco de dados com suas descrições corretas, caso precise extrair um relatório, por exemplo.

Normalmente, tenho um pequeno trecho de código que se conectará ao banco de dados e verificará se os status listados em uma tabela específica têm todos os mesmos valores de id / nome que eu codifiquei na memória. Se não corresponderem, abortarei a execução do software.

Dependendo das suas necessidades, convém implementar comportamentos ligeiramente diferentes, mas no geral é uma boa ideia ter esses status codificados de qualquer maneira.

Alex
fonte
2

Temos problemas semelhantes no meu projeto (código legado, viva!) O grande problema é que "as tabelas enum nunca mudam" até que o código seja alterado. Eu tenho duas estratégias para mitigar as quais eu tenho migrado lentamente.

Primeiro, e melhor, é eliminar as referências diretas a esses valores sempre que possível. Sempre pergunte: "por que preciso usar diretamente o valor de enum?" Em muitos casos, isso é um sinal de que o código tem muitas suposições codificadas ou está tentando fazer muita manipulação nos dados. Veja se você não pode estabelecer melhores relacionamentos no banco de dados ou um código mais flexível para lidar com o que está sendo manipulado.

Quando isso não funciona, vou para o plano B: geração de código. Como as tabelas mudam com pouca frequência e publicamos novas compilações regularmente, um gerador de código pode ler as tabelas enum e escrever o código enum. Essa biblioteca gerada dinamicamente é usada no projeto. Se o banco de dados mudar, a próxima compilação não será compilada, o que é muito melhor do que obter erros de tempo de execução misteriosos.

CodexArcanum
fonte
Como você eliminaria referências a um enum? Por exemplo, você está classificando ou pesquisando por um status neste caso. Ter algum valor mágico no DB também não é bom para mim. É para isso que servem as tabelas de pesquisa.
Nportelli 28/01
No passado, eu fiz o oposto. Sempre que houver alteração de código no Enum, na inicialização do aplicativo, ele sincroniza esses valores com o Banco de Dados. Aqui o código é a fonte da verdade. Banco de dados é uma representação dele. Normalmente, ignoro valores no banco de dados que o código não pode compreender, mas dessa forma, recebo um mecanismo para limpar automaticamente o banco de dados, se necessário.
Anshul