Utilizei com sucesso a seguinte metodologia, elaborada no Controle de Versão e no seu Banco de Dados :
- manter um número de versão em metadados (eu uso uma propriedade estendida do banco de dados)
- qualquer alteração de esquema é codificada como um script que é atualizado da versão atual para a próxima versão
- O aplicativo é enviado com todos os scripts para atualizar da versão 0 (implantação inicial) até a versão atual
- Toda mudança é feita através de um script. A inclusão de alterações de dados do 'sistema', como dicionários e entradas da tabela de pesquisa.
- Quando implementado, o aplicativo verifica a versão do esquema em disco e executa todas as etapas de atualização para trazer o esquema para a versão necessária atual
Costumo ouvir a opinião de 'como isso é diferente de apenas manter os scripts de definição de objeto sob controle de origem?'. A diferença é enorme, porque quando você implanta uma nova versão do seu aplicativo, não cria simplesmente um novo banco de dados. Na maioria das vezes, seu aplicativo precisará atualizar o banco de dados existente, incluindo os dados existentes . Essa é uma diferença crucial. Suas etapas de atualização precisam garantir a integridade e a consistência dos dados existentes durante a atualização. Algumas operações são triviais no código (adicione uma coluna não anulável com valor padrão ao script de definição de objeto de tabela, concluído), mas na verdade são extremamente dolorosas na implantação real (a tabela possui 1,5 bilhão de linhas, a coluna de adição acabaria espaço de log, se feito da maneira "simplória").
Como isso funciona com a ramificação:
- quando a ramificação é criada, ela captura a versão atual do esquema, por exemplo, versão 1.6
- quando a equipe começa a trabalhar na filial, ela adiciona uma nova versão, 1.7, e começa a codificar a etapa de atualização de 1.6 para 1.7
- a etapa de atualização é alterada conforme as modificações são feitas na ramificação. Ele sempre executa o script que atualiza da v 1.6 para a 1.7, mas o que exatamente esses scripts fazem está sujeito às iterações e check-ins normais de código na ramificação
- Quando o ramo termina o desenvolvimento, ele se prepara para a integração reversa (a ser mesclada de volta à linha de base)
- ele faz uma nova integração direta da linha de base à filial. Se a integração não trouxer alterações para a versão do esquema, tudo ficará bem, o ramo poderá reverter a integração como está. a versão 1.7 se torna a nova versão da linha de base.
- o interessante é quando outro ramo se integra inversamente à base nesse meio tempo e agora a versão do esquema base foi alterada para, digamos, 1,7. Nesse caso, nossa filial precisa aumentar a versão do esquema de destino de implantação para 1.8 e fazer uma revisão da etapa de atualização que era anteriormente de 1.6 para 1.7 para ver como ela opera no novo ambiente, atualizando de 1.7 para 1.8. Os conflitos de esquema lógico precisam ser resolvidos, o script pode exigir alterações, o teste deve ser feito. Uma vez concluído, o ramo pode reverter a integração na base. A versão de destino implementada do produto agora é 1.8.
- quando outro ramo que bifurcou na versão 1.6 do esquema quiser se integrar de forma reversa, ele precisará elevar sua versão do esquema para 1.9, testar o script de atualização de 1.8 para 1.9, para que possa se integrar novamente à base.
Observe que não há nenhuma ferramenta envolvida, nenhum script de diff de esquema mágico, nenhum assistente e nenhum script de botão direito do mouse gerado. Este é um processo 100% orientado ao desenvolvedor, baseado na fonte (scripts). Muitos acham todo esse processo elaborado, mas funciona. De fato, como usuário do SQL Server, você já aproveitou os resultados desse processo no uso diário do SQL Server: o próprio SQL Server usa um processo de atualização de banco de dados muito semelhante e, como você provavelmente espera, o processo de desenvolvimento de produtos faz uso extensivo de ramificação e o problema que você mencionou é um problema muito real que precisa ser resolvido.
BTW, como a ramificação / integração realmente ocorre difere entre os produtos de controle de origem, estou usando os termos familiares do modo de operação de integração forçada .