Pergunta

Esta parece ser uma área negligenciada que realmente precisa de alguns insights.Quais são suas melhores práticas para:

  • fazendo um procedimento de atualização
  • recuando em caso de erros
  • sincronizando alterações de código e banco de dados
  • testes antes da implantação
  • mecânica de modificação da tabela

etc...

Foi útil?

Solução

Essa é uma ótima pergunta.(Há uma grande chance de que isso acabe em um debate sobre banco de dados normalizado versus desnormalizado... que não vou começar...ok agora para algumas sugestões.)

algumas coisas que pensei que fiz (acrescentarei mais quando tiver mais tempo ou precisar de uma pausa)

design do cliente - é aqui que o método VB de sql embutido (mesmo com instruções preparadas) causa problemas.Você pode gastar MUITOS apenas encontrando essas declarações.Se você usar algo como Hibernate e colocar o máximo de SQL em consultas nomeadas você terá um único lugar para a maior parte do sql (nada pior do que tentar testar o sql que está dentro de alguma instrução IF e você simplesmente não apertar o "gatilho" critérios em seu teste para essa instrução IF).Antes de usar o hibernate (ou outros orms), quando eu faria SQL diretamente em JDBC ou ODBC, eu colocaria todas as instruções sql como campos públicos de um objeto (com uma convenção de nomenclatura) ou em um arquivo de propriedades (também com uma nomenclatura convenção para os valores diz PREP_STMT_xxxx.E use reflexão ou iteração sobre os valores na inicialização em a) casos de teste b) inicialização do aplicativo (alguns rdbms permitem pré-compilar com instruções preparadas antes da execução, portanto, na inicialização após o login, eu pré-compilaria a preparação stmts na inicialização para fazer o autoteste do aplicativo.Mesmo para centenas de declarações em um bom rdbms, isso leva apenas alguns segundos.e apenas uma vez.E isso salvou muito minha bunda.Em um projeto, os DBAs não se comunicavam (uma equipe diferente, em um país diferente) e o esquema parecia mudar NOITE, sem motivo.E todas as manhãs recebíamos uma lista de onde exatamente o aplicativo quebrou, na inicialização.

Se você precisar de funcionalidade adhoc, coloque-a em uma classe bem nomeada (ou seja,novamente, uma convenção de nomenclatura ajuda no teste automático) que atua como uma espécie de fábrica para sua consulta (ou seja,ele cria a consulta).Você terá que escrever o código equivalente de qualquer maneira, basta colocá-lo em um local onde possa testá-lo.Você pode até escrever alguns métodos de teste básicos no mesmo objeto ou em uma classe separada.

Se puder, tente também usar procedimentos armazenados.Eles são um pouco mais difíceis de testar como acima.Alguns bancos de dados também não pré-validam o sql em procs armazenados em relação ao esquema em tempo de compilação apenas em tempo de execução.Geralmente envolve, digamos, fazer uma cópia da estrutura do esquema (sem dados) e, em seguida, criar todos os processos armazenados nessa cópia (caso a equipe do banco de dados que fez as alterações não tenha validado corretamente).Assim a estrutura pode ser verificada.mas como ponto de gerenciamento de mudanças, os processos armazenados são ótimos.Na mudança, todos entendem.Especialmente quando as alterações no banco de dados são resultado de alterações nos processos de negócios.E todas as linguagens (java, vb, etc recebem a alteração)

Normalmente também configuro uma tabela que uso chamada system_setting etc.Nesta tabela mantemos um identificador VERSION.Isso ocorre para que as bibliotecas clientes possam se conectar e validar se são válidas para esta versão do esquema.Dependendo das alterações no seu esquema, você não deseja permitir que os clientes se conectem se eles puderem corromper o seu esquema (ou seja,você não tem muitas regras referenciais no banco de dados, mas no cliente).Depende se você também terá várias versões de cliente (o que acontece em aplicativos NÃO Web, ou seja,eles estão executando o binário errado).Você também pode ter ferramentas em lote, etc.Outra abordagem que também fiz foi definir um conjunto de esquemas para versões de operação em algum tipo de arquivo de propriedades ou novamente em uma tabela system_info.Esta tabela é carregada no login e, em seguida, usada por cada "gerente" (normalmente tenho algum tipo de API do lado do cliente para fazer a maioria das coisas do banco de dados) para validar essa operação se for a versão correta.Assim, a maioria das operações pode ser bem-sucedida, mas você também pode falhar (lançar alguma exceção) em métodos desatualizados e informar POR QUÊ.

gerenciando a mudança no esquema -> você atualiza a tabela ou adiciona relacionamentos 1-1 a novas tabelas?Tenho visto muitas lojas que sempre acessam dados por meio de uma visualização por esse motivo.Isso permite que os nomes das tabelas sejam alterados, colunas etc.Eu brinquei com a ideia de realmente tratar visualizações como interfaces em COM.ou seja.você adiciona uma nova VIEW para novas funcionalidades/versões.Muitas vezes, o que o leva até aqui é que você pode ter muitos relatórios (especialmente relatórios personalizados do usuário final) que assumem formatos de tabela.As visualizações permitem implantar um novo formato de tabela, mas oferecem suporte a aplicativos clientes existentes (lembre-se de todos aqueles relatórios ad hoc incômodos).

Além disso, é necessário escrever scripts de atualização e reversão.e novamente TESTE, TESTE, TESTE...

------------ OK - ESTE É UM TEMPO DE DISCUSSÃO UM POUCO ALEATÓRIO --------------

Na verdade, tinha um grande projeto comercial (ou seja,loja de software) onde tivemos o mesmo problema.A arquitetura era de 2 camadas e eles estavam usando um produto um pouco parecido com PHP, mas pré-php.Mesma coisa.nome diferente.de qualquer forma eu entrei na versão 2....

Estava custando MUITO DINHEIRO para fazer atualizações.Bastante.ou seja.doe semanas de consultoria gratuita no local.

E estava chegando ao ponto de querer adicionar novos recursos ou otimizar o código.Parte do código existente usava procedimentos armazenados, então tínhamos pontos em comum onde poderíamos gerenciar o código.mas outras áreas eram essa marcação sql incorporada em html.O que foi ótimo para chegar ao mercado rapidamente, mas com cada interação de novos recursos o custo de teste e manutenção pelo menos dobrou.Então, quando estávamos pensando em extrair o código do tipo php, colocar camadas de dados (isso foi 2001-2002, antes de qualquer ORM, etc.) e adicionar muitos recursos novos (feedback do cliente), analisamos esta questão de como projetar ATUALIZAÇÕES no sistema.O que é um grande negócio, já que as atualizações custam muito dinheiro para serem feitas corretamente.Agora, a maioria dos padrões e todas as outras coisas que as pessoas discutem com um certo grau de energia lidam com o código OO que está em execução, mas e quanto ao fato de que seus dados precisam a) integrar-se a essa lógica, b) o significado e também a estrutura de os dados podem mudar com o tempo e, muitas vezes, devido à forma como os dados funcionam, você acaba com muitos subprocessos/aplicativos na organização do seu cliente que precisam desses dados -> relatórios ad hoc ou qualquer relatório personalizado complexo, bem como trabalhos em lote que foram feitos para feeds de dados personalizados, etc.

Com isso em mente comecei a brincar com algo um pouco fora do campo.Ele também tem algumas suposições.a) os dados são mais lidos do que gravados.b) as atualizações acontecem, mas não nos níveis dos bancos, ou seja.um ou dois por segundo, digamos.

A ideia era aplicar uma visualização COM/Interface de como os dados eram acessados ​​pelos clientes em um conjunto de tabelas CONCRETE (que variavam com as alterações de esquema).Você pode criar uma visualização separada para cada operação de tipo - atualizar, excluir, inserir e ler.Isso é importante.As visualizações seriam mapeadas diretamente para uma tabela ou permitiriam o acionamento de uma tabela fictícia que faz atualizações ou inserções reais, etc.O que eu realmente queria era algum tipo de indireção de nível captável que ainda pudesse ser usada por relatórios de cristal, etc.NOTA - Para inserções, atualizações e exclusões, você também pode usar procs armazenados.E você tinha uma versão para cada versão do produto.Dessa forma sua versão 1.0 tinha sua versão do esquema, e se as tabelas mudassem, você ainda teria as VIEWS da versão 1.0 mas com NOVA lógica de backend para mapear para as novas tabelas conforme necessário, mas você também teria visualizações da versão 2.0 que suportariam novos campos etc.Na verdade, isso foi apenas para oferecer suporte a relatórios ad hoc, que, se você é um NEGÓCIO e não um programador, é provavelmente o motivo pelo qual você tem o produto.(seu produto pode ser uma porcaria, mas se você tiver os melhores relatórios do mundo, você ainda pode ganhar, o inverso é verdadeiro - seu produto pode ter o melhor recurso em termos de recursos, mas se for o pior em relatórios, você pode facilmente perder).

ok, espero que algumas dessas idéias ajudem.

Outras dicas

Liquibase

liquibase.org:

  1. ele entende as definições de hibernação.
  2. gera melhor atualização de esquema sql do que hibernar
  3. ele registra quais atualizações foram feitas em um banco de dados
  4. ele lida com mudanças em duas etapas (ou seja,exclua uma coluna "foo" e renomeie uma coluna diferente para "foo")
  5. ele lida com o conceito de atualizações condicionais
  6. o desenvolvedor realmente escuta a comunidade (com o hibernate, se você não estiver na multidão ou for um novato - você será basicamente ignorado).

http://www.liquibase.org

opinião

a aplicação deverá nunca lidar com uma atualização de esquema.Isso é um desastre esperando para ocorrer.Os dados duram mais que os aplicativos e, assim que vários aplicativos tentam trabalhar com os mesmos dados (o aplicativo de produção + um aplicativo de relatórios, por exemplo), é provável que ambos usem as mesmas bibliotecas subjacentes da empresa...e então ambos os programas decidem fazer sua própria atualização de banco de dados ...divirta-se com que bagunça.

Eu sou um grande fã de Portão Vermelho produtos que ajudam a criar pacotes SQL para atualizar esquemas de banco de dados.Os scripts de banco de dados podem ser adicionados ao controle de origem para ajudar no controle de versão e na reversão.

Em geral minha regra é:"O aplicativo deve gerenciar seu próprio esquema."

Isso significa que os scripts de atualização de esquema fazem parte de qualquer pacote de atualização do aplicativo e são executados automaticamente quando o aplicativo é iniciado.Em caso de erros, o aplicativo falha ao iniciar e a transação do script de atualização não é confirmada.A desvantagem disso é que o aplicativo precisa ter acesso total para modificação do esquema (isso irrita os DBAs).

Tive grande sucesso usando o recurso SchemaUpdate do Hibernates para gerenciar as estruturas da tabela.Deixar os scripts de atualização para lidar apenas com a inicialização real dos dados e a remoção ocasional de colunas (SchemaUpdate não faz isso).

Em relação aos testes, como as atualizações fazem parte da aplicação, testá-las passa a fazer parte do ciclo de testes da aplicação.

Reflexão tardia:Levando em conta algumas das críticas em outras postagens aqui, observe que a regra diz “é própria”.Só se aplica realmente onde a aplicação possui o esquema, como geralmente acontece com software vendido como produto.Se o seu software estiver compartilhando um banco de dados com outro software, use outros métodos.

Todos esses são tópicos importantes, mas aqui está minha recomendação para atualização.

Você não especificou sua plataforma, mas para ambientes de construção NANT eu uso Tarantino.Para cada atualização de banco de dados que você está pronto para confirmar, você cria um script de alteração (usando RedGate ou outra ferramenta).Quando você passa para produção, Tarantino verifica se o script foi executado no banco de dados (ele adiciona uma tabela ao seu banco de dados para acompanhar).Caso contrário, o script é executado.É preciso todo o trabalho manual (leia:erro humano) fora do gerenciamento de versões do banco de dados.

Como Pat disse, use liquibase.Especialmente quando você tem vários desenvolvedores com seus próprios bancos de dados de desenvolvimento, fazendo alterações que se tornarão parte do banco de dados de produção.

Se houver apenas um desenvolvedor, como em um projeto em que estou agora (ha), eu apenas confirmo as alterações de esquema como arquivos de texto SQL em um repositório CVS, que verifico em lotes no servidor de produção quando as alterações de código entram .

Mas o liquibase é mais bem organizado que isso!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top