Houve alguma discussão no wiki da comunidade SO sobre se os objetos de banco de dados devem ser controlados por versão. No entanto, não vi muita discussão sobre as melhores práticas para criar um processo de automação de construção para objetos de banco de dados.
Esse tem sido um ponto de discussão controverso para minha equipe - principalmente porque os desenvolvedores e DBAs costumam ter objetivos, abordagens e preocupações diferentes ao avaliar os benefícios e riscos de uma abordagem de automação para implantação de banco de dados.
Eu gostaria de ouvir algumas idéias da comunidade SO sobre quais práticas têm sido eficazes no mundo real.
Sei que é um tanto subjetivo quais práticas são realmente melhores, mas acho que um bom diálogo sobre qual trabalho pode ser útil para muitas pessoas.
Aqui estão algumas das minhas perguntas preliminares sobre áreas de interesse neste tópico. Não se trata de uma lista definitiva, mas sim de um ponto de partida para as pessoas entenderem o que procuro.
- Os ambientes de teste e produção devem ser criados a partir do controle de origem?
- Ambos devem ser desenvolvidos usando automação - ou a produção deve ser construída copiando objetos de um ambiente de teste finalizado e estável?
- Como você lida com as diferenças potenciais entre os ambientes de teste e produção em scripts de implantação?
- Como você testa se os scripts de implantação funcionarão de maneira tão eficaz na produção quanto no teste?
- Quais tipos de objetos devem ter controle de versão?
- Apenas código (procedimentos, pacotes, gatilhos, java, etc)?
- Índices?
- Restrições?
- Definições de tabela?
- Scripts de mudança de tabela? (por exemplo, scripts ALTER)
- Tudo?
- Quais tipos de objetos não devem ter controle de versão?
- Sequências?
- Bolsas?
- Contas de usuário?
- Como os objetos de banco de dados devem ser organizados em seu repositório SCM?
- Como você lida com coisas únicas, como scripts de conversão ou scripts ALTER?
- Como você lida com a retirada de objetos do banco de dados?
- Quem deve ser responsável por promover objetos desde o desenvolvimento até o nível de teste?
- Como você coordena as mudanças de vários desenvolvedores?
- Como você lida com a ramificação de objetos de banco de dados usados por vários sistemas?
- Que exceções, se houver, podem ser feitas razoavelmente neste processo?
- Problemas de segurança?
- Dados com problemas de desidentificação?
- Scripts que não podem ser totalmente automatizados?
- Como você pode tornar o processo resiliente e aplicável?
- Erro de desenvolvedor?
- Para questões ambientais inesperadas?
- Para recuperação de desastres?
- Como você convence os tomadores de decisão de que os benefícios do DB-SCM realmente justificam o custo?
- Provas anedóticas?
- Pesquisa da indústria?
- Recomendações de práticas recomendadas do setor?
- Apelos a autoridades reconhecidas?
- Análise de custo-benefício?
- Quem deve "possuir" objetos de banco de dados neste modelo?
- Desenvolvedores?
- DBAs?
- Analistas de dados?
- Mais de um?
fonte
Respostas:
Aqui estão algumas respostas às suas perguntas:
fonte
Eu trato o SQL como código-fonte quando possível
Se eu puder escrevê-lo no SQL compatível com o padrão, ele geralmente vai para um arquivo no meu controle de origem. O arquivo definirá o máximo possível, como SPs, instruções Table CREATE.
Também incluo dados fictícios para teste no controle de origem:
E então eu abstraio todas as minhas consultas SQL para que eu possa construir o projeto inteiro para MySQL, Oracle, MSSQL ou qualquer outra coisa.
A automação de compilação e teste usa esses scripts de compilação, pois eles são tão importantes quanto a origem do aplicativo e testa tudo, desde integridade até gatilhos, procedimentos e registro.
fonte
Usamos integração contínua via TeamCity. Em cada check-in para o controle de origem, o banco de dados e todos os dados de teste são reconstruídos do zero, em seguida, o código e os testes de unidade são executados no código. Se você estiver usando uma ferramenta de geração de código como CodeSmith, ela também pode ser colocada em seu processo de compilação para gerar sua camada de acesso a dados nova com cada compilação, certificando-se de que todas as suas camadas "combinem" e não produzam erros devido a parâmetros SP incompatíveis ou colunas ausentes.
Cada construção tem sua própria coleção de scripts SQL que são armazenados no diretório $ project \ SQL \ no controle de origem, atribuídos a um prefixo numérico e executados em ordem. Dessa forma, estamos praticando nosso procedimento de implantação em cada build.
Dependendo da tabela de pesquisa, a maioria dos nossos valores de pesquisa também são armazenados em scripts e executados para garantir que os dados de configuração sejam os que esperamos, digamos, "reason_codes" ou "country_codes". Dessa forma, podemos fazer uma alteração nos dados de pesquisa no dev, testá-los e "promovê-los" por meio de controle de qualidade e produção, em vez de usar uma ferramenta para modificar os valores de pesquisa na produção, o que pode ser perigoso para o tempo de atividade.
Também criamos um conjunto de scripts de "rollback" que desfazem as alterações do nosso banco de dados, no caso de um build para produção dar errado. Você pode testar os scripts de rollback executando-os e, em seguida, executando novamente os testes de unidade para a versão de compilação abaixo da sua, após a execução dos scripts de implantação.
fonte
+1 para Liquibase : LiquiBase é uma biblioteca independente de banco de dados de código aberto (LGPL) para rastrear, gerenciar e aplicar alterações de banco de dados. Ele é construído em uma premissa simples: todas as alterações do banco de dados (estrutura e dados) são armazenadas de maneira descritiva baseada em XML e verificadas no controle de origem. O bom ponto é que as alterações DML são armazenadas semanticamente, não apenas diff, para que você possa rastrear o propósito das alterações.
Ele pode ser combinado com o controle de versão GIT para uma melhor interação. Vou configurar nosso ambiente dev-prod para testá-lo.
Você também pode usar Maven, sistemas de construção Ant para construir código de produção a partir de scripts.
A desvantagem é que LiquiBase não se integra a IDE SQL difundidos e você mesmo deve fazer as operações básicas.
Além disso, você pode usar DBUnit para teste de banco de dados - esta ferramenta permite que scripts de geração de dados sejam usados para testar seu ambiente de produção com limpeza posterior.
NA MINHA HUMILDE OPINIÃO:
Enfrentamos todos os problemas mencionados com alterações de código, fusão, reescrita em nosso banco de dados de produção de faturamento. Este tópico é ótimo para descobrir tudo isso.
fonte
Ao fazer "perguntas teaser", você parece estar mais interessado em uma discussão do que na opinião de alguém sobre as respostas finais. A lista de discussão ativa (> 2500 membros) agileDatabases abordou muitas dessas questões e é, na minha experiência, um fórum sofisticado e civil para esse tipo de discussão.
fonte
Eu basicamente concordo com todas as respostas dadas pela van . Para mais informações, minha linha de base para gerenciamento de banco de dados é a série K. Scott Allen (uma leitura obrigatória, IMHO. E a opinião de Jeff também parece).
Create.sql
. Isso pode incluir a inserção de dados estáticos (listas ...).Create.sql
:Create.cmd
. Seu objetivo é principalmente verificar os pré-requisitos (ferramentas, variáveis de ambiente ...) e enviar parâmetros para o script SQL. Ele também pode carregar dados estáticos em massa de arquivos CSV para problemas de desempenho.Create.cmd
arquivo.IMHO, o carregamento dinâmico de dados deve exigir outra etapa, dependendo do seu ambiente. Os desenvolvedores desejarão carregar seu banco de dados com teste, lixo ou nenhum dado, enquanto na outra extremidade os gerentes de produção desejarão carregar os dados de produção. Eu consideraria armazenar dados de teste no controle de origem também (para facilitar o teste de unidade, por exemplo).
Assim que a primeira versão do banco de dados for colocada em produção, você precisará não apenas criar scripts (principalmente para desenvolvedores), mas também atualizar scripts (com base nos mesmos princípios):
Upgrade.sql
arquivo (que pode chamar outros) que permite a atualização da versão N-1 para a versão N (sendo N a versão que está sendo lançada). Eu armazeno este script em uma pasta chamadaN-1
.Upgrade.cmd
. Ele pode recuperar a versão atual (CV) do banco de dados por meio de uma instrução SELECT simples, iniciar oUpgrade.sql
script armazenado naCV
pasta e fazer um loop até que nenhuma pasta seja encontrada. Dessa forma, você pode atualizar automaticamente de, digamos, N-3 para N.Os problemas são:
Quanto a que tipo de objetos de banco de dados você deseja ter sob controle de origem? Bem, eu diria o máximo possível, mas não mais ;-) Se você deseja criar usuários com senhas, obtenha uma senha padrão (login / login, prático para fins de teste de unidade) e faça da alteração de senha uma operação manual . Isso acontece muito com o Oracle, onde os esquemas também são usuários ...
fonte
Temos nosso projeto Silverlight com banco de dados MSSQL no controle de versão Git. A maneira mais fácil é ter certeza de que você tem um banco de dados reduzido (em termos de conteúdo) e fazer um despejo completo do Visual Studio. Então você pode fazer 'sqlcmd' a partir de seu script de construção para recriar o banco de dados em cada máquina de desenvolvimento.
Para implantação, isso não é possível porque os bancos de dados são muito grandes: essa é a principal razão para tê-los em um banco de dados em primeiro lugar.
fonte
Eu acredito fortemente que um banco de dados deve fazer parte do controle de origem e, em grande parte, do processo de construção. Se estiver no controle de origem, eu tenho as mesmas proteções de codificação ao escrever um procedimento armazenado em SQL e ao escrever uma classe em C #. Eu faço isso incluindo um diretório de scripts de banco de dados em minha árvore de origem. Este diretório de script não tem necessariamente um arquivo para um objeto no banco de dados. Isso seria um pé no saco! Eu desenvolvo no meu banco de dados apenas como faria no meu projeto de código. Então, quando estou pronto para fazer o check-in, faço uma comparação entre a última versão do meu banco de dados e a atual em que estou trabalhando. Eu uso o SQL Compare para isso e ele gera um script de todas as mudanças. Este script é então salvo em meu diretório db_update com uma convenção de nomenclatura específica 1234_TasksCompletedInThisIteration em que o número é o próximo número no conjunto de scripts já existentes e o nome descreve o que está sendo feito neste check-in. Eu faço isso desta forma porque parte do meu processo de construção eu começo com um novo banco de dados que é então construído programaticamente usando os scripts neste diretório. Eu escrevi uma tarefa NAnt personalizada que itera por meio de cada script que executa seu conteúdo no banco de dados vazio. Obviamente, se eu precisar de alguns dados para entrar no banco de dados, também tenho scripts de inserção de dados. Isso tem muitos benefícios também. Um, todas as minhas coisas são versionadas. Dois, cada construção é uma nova construção, o que significa que não haverá qualquer coisa sorrateira entrando no meu processo de desenvolvimento (como dados sujos que causam estranhezas no sistema). Terceiro, quando um novo cara é adicionado à equipe de desenvolvimento, ele simplesmente precisa obter o mais recente e seu desenvolvedor local é criado para ele imediatamente. Quatro, posso executar casos de teste (não chamei de "teste de unidade"!) Em meu banco de dados, pois o estado do banco de dados é redefinido com cada compilação (o que significa que posso testar meus repositórios sem me preocupar em adicionar dados de teste ao db).
Isso não é para todos.
Isso não é para todos os projetos. Eu costumo trabalhar em projetos verdes, o que me permite essa comodidade!
fonte
Em vez de entrar em argumentos de torre branca, aqui está uma solução que funcionou muito bem para mim em problemas do mundo real.
Construir um banco de dados do zero pode ser resumido como o gerenciamento de scripts sql.
DBdeploy é uma ferramenta que verifica o estado atual de um banco de dados - por exemplo, quais scripts foram executados anteriormente nele, quais scripts estão disponíveis para serem executados e, portanto, quais scripts são necessários para serem executados.
Em seguida, ele agrupará todos os scripts necessários e os executará. Em seguida, ele registra quais scripts foram executados.
Não é a ferramenta mais bonita nem a mais complexa - mas com um gerenciamento cuidadoso pode funcionar muito bem. É open source e facilmente extensível. Depois que a execução dos scripts é bem tratada, é fácil adicionar alguns componentes extras, como um script de shell que verifica os scripts mais recentes e executa o dbdeploy em uma instância específica.
Veja uma boa introdução aqui:
http://code.google.com/p/dbdeploy/wiki/GettingStarted
fonte
Você pode descobrir que a Liquibase lida com muito do que você está procurando.
fonte
Cada desenvolvedor deve ter seu próprio banco de dados local e usar o controle do código-fonte para publicar para a equipe. Minha solução está aqui: http://dbsourcetools.codeplex.com/ Divirta-se, - Nathan
fonte