Refatoração ou atualização de bancos de dados para lidar com novos recursos


9

Várias respostas a uma pergunta de esquema do banco de dados sugeriram uma tabela adicional para normalizar um banco de dados para um recurso que não faz parte dos requisitos atuais (uma tabela UserDepartment para permitir um relacionamento muitos para muitos entre funcionários / usuários e diferentes departamentos que eles podem pertence a.).

Não contra a normalização. Parece que quando se trata de design de banco de dados, há um forte impulso para incluir recursos que eles 'têm certeza' de que alguém desejará no futuro. É tão difícil adicionar tabelas / campos ao banco de dados para acomodar recursos que há uma tendência a projetar demais? Eles não seriam refatorados ou atualizados, assim como o resto do aplicativo, se necessário? Refazer as coisas nunca é divertido, mas é possível mover dados de uma tabela para outra. Só não tenho certeza de onde essa linha de pensamento terminará.

Edit: Há tanta aversão a isso, eu me pergunto quantos projetos acabam não adicionando um recurso que requer uma alteração drástica no banco de dados ou são abordagens não normalizadas adotadas como adicionar um campo DepartmentID2 em vez de uma nova tabela. A necessidade de vários departamentos para um funcionário é um problema de domínio comum. Apenas não notei muitos esquemas de banco de dados repletos de relacionamentos muitos-para-muitos.


11
+1 Obrigado por perguntar isso. Aprendi muito lendo as respostas à minha pergunta original, e esse é um tópico interessante também.
Jim

Respostas:


3

Há um livro inteiro escrito sobre refatoração de banco de dados. Assim como na refatoração de código, existem maneiras padrão de refatoração de banco de dados. A única diferença é que, ao fazer a refatoração de código, você não precisa considerar o estado do objeto / código, enquanto nos bancos de dados você deve considerar os dados, porque perder dados não é bom para os usuários (ou para qualquer um, na verdade )

Você pode ler mais sobre refatoração de banco de dados aqui .


Este site foi o que levou a pergunta em primeiro lugar;)
JeffO 07/10

14

O código de refatoração é fácil - você simplesmente altera o código e executa seus testes de regressão.

A refatoração de bancos de dados é difícil - é necessário mover (uma quantidade potencialmente enorme) de dados, garantir que nenhum deles seja descartado, garantir que as restrições sejam mantidas no novo esquema. E, se você tiver requisitos de auditoria para os dados, precisará explicar por que eles estão organizados de maneira diferente e poder associar os dados do pré-refoctor aos dados do pós-refatoração. Além disso, nenhum de seus backups antigos corresponderá ao novo esquema, que é outro risco.

Coisas assustadoras.


Os testes do banco de dados não devem ser diferentes. Todas as alterações requerem uma auditoria e afetam os backups. Quantos dados você acumulará antes de reconhecer essa necessidade? Se você converteu dados, esse recurso seria ainda mais óbvio.
JeffO 29/09

8
+1 para @Mathew Flynn. Quantos dados você acumulará antes de reconhecer essa necessidade? MILHÕES de linhas. Outro problema é que muitas vezes o seu aplicativo não é a única coisa que usa o banco de dados. O banco de dados pode ter muitos aplicativos trabalhando com ele e você pode nem saber que eles existem (por exemplo, aplicativos "BI" selvagens). Alterações nos esquemas de banco de dados são assustadoras.
Angelo

2
Às vezes bilhões de linhas
HLGEM

11
Se você está lidando com bilhões de linhas, é melhor saber como movê-las
JeffO

3

Existe uma linha tênue entre gastar muito tempo com engenharia excessiva e investir um pouco do seu tempo para adicionar apenas recursos suficientes para economizar uma quantidade considerável de tempo no futuro.


11
Você poderia argumentar em uma ou duas instâncias isoladas, mas quando os 'bits' de tempo somam muito?
JeffO 29/09

Da minha própria experiência, é realmente o caso da grande maioria dos projetos. Mas eu também acho que ele vem com experiência e é altamente subjetivo :) Eu ficaria surpreso se alguém puder lhe dar uma receita exata (daí a 'linha tênue').
0x4B1D

@ Jeff O: Não vai ser 'bits'. É necessário um investimento de 10% ou 20% do tempo de desenvolvimento no fortalecimento, porque o sistema pode durar mais do que o prazo originalmente previsto e o seu emprego.
Rwong 30/09

3

Penso que a teoria é que, se você incluir uma tabela de links para suportar um relacionamento muitos para muitos entre duas tabelas, mesmo que existam realmente apenas muitos para um nos dados, todos escreverão o SQL de tal maneira que, se alguma vez houver um muitos para muitos são suportados, tudo "funcionará".

Na prática, nem sempre achei que isso fosse verdade, mas suponho que o SQL esteja mais próximo do que precisa ser para oferecer suporte a muitos a muitos do que seria de outra forma.

Mas, para chegar especificamente à sua pergunta, na verdade existe uma quantidade considerável de dor convertendo um relacionamento de 1 para muitos para muitos para muitos. O motivo é que o SQL não é projetado com os mesmos tipos de objetivos de encapsulamento dos objetos, e a maioria das consultas usa mais tabelas na camada de banco de dados do que as pessoas se sentiriam confortáveis ​​em ter um objeto na camada de negócios.

Portanto, uma alteração no relacionamento muitos para muitos afetará todas as consultas que envolvem as 2 tabelas originais, geralmente um efeito em cascata muito mais amplo do que o que ocorrerá na camada de negócios. Então, as pessoas se esforçam para impedir que isso aconteça.

IMHO isso não seria necessário se tivéssemos uma linguagem melhor que SQL para especificar a álgebra relacional. Se fosse possível criar uma consulta SQL, peça por peça, por objetos que não precisassem de visibilidade para todas as tabelas da consulta, isso não aconteceria. Coisas como o LINQ (para SQL ou para Entidades) tentam resolver isso, mas é uma solução muito complexa e difícil de otimizar (e eu já estive em grupos de usuários de DBA nos quais o LINQ é mencionado e um gemido coletivo sobe sempre). Sonho com uma linguagem de banco de dados universalmente suportada com funções de álgebra relacional de primeira classe ...

Enquanto isso, sim, você pode refatorar de 1 para muitos para muitos para muitos, mas pode ser muito trabalhoso.


Você não vai transformar todo relacionamento em muitos-para-muitos?
91111 JeffO

@ Jeff O - Não sei se entendi sua pergunta. Em caso de dúvida, eu modelo o número de muitos para muitos para evitar as armadilhas mencionadas em várias respostas à sua pergunta original. Fiquei um pouco mais cauteloso com isso depois de manter os bancos de dados que realmente fizeram quase todos os relacionamentos de muitos para muitos, porque eles acabaram fazendo coisas como criar visualizações que faziam os relacionamentos parecerem um para muitos (que, na prática, todos eles foram). Então eles tiveram o pior dos dois mundos. Eu nunca tive isso acontecer nos meus próprios projetos, mas é uma história de advertência.
Psr

3

Eu normalmente explico desta maneira para os PHBs - o código são as paredes e o teto, o banco de dados é a base.

Mover as paredes e mudar o telhado pode ser feito. Mudar a fundação requer muita escavação e reconstrução das paredes e do teto.

O que desenvolvedores inexperientes (e professores universitários) dizem é "excesso de engenharia" é o que desenvolvedores experientes chamam de "prova de futuro". Apesar do que a especificação diz, você sabe o que provavelmente mudará durante o ALM ou onde os problemas de desempenho ocorrerão, portanto, você deseja ajustar a estrutura da tabela para começar.

A implementação de scripts de atualização nos servidores do cliente é um projeto não trivial e os DBAs de todos os clientes estão por toda parte, e você deseja fazer a verificação tripla de tudo. Algumas colunas e tabelas extras não são tão ruins, afinal.


1

A regra geral é que se um relacionamento é um para um, mas no futuro pode ser muitos para muitos, então torna-se um número para muitos.

O funcionário / departamento é um exemplo clássico. Na maioria das pequenas empresas, esse é efetivamente um relacionamento entre muitos na maioria das vezes . No entanto, quase sempre existe uma situação em que muitos se tornam muitos - um de seus engenheiros passa para a gerência, mas ainda é responsável por oferecer suporte a um produto que ele desenvolveu enquanto estava na engenharia, ou um de seus vendedores mudou-se para desenvolvimento de produtos, mas, como ele tem um relacionamento próximo com um cliente importante, ele ainda é o principal vendedor desse cliente.

Não custa muito mais se um para muitos for implementado como muitos para muitos - mas refatorar um banco de dados e aplicativo para suportar muitos para muitos é caro e cheio de dificuldades.


Concordo que existem muitos domínios maduros (como RH) em que o cliente não antecipa a necessidade, mas você sabe que isso acontecerá.
Jeffo

0

Há duas maneiras de analisar o design de software (e provavelmente muitas outras coisas) - uma visão tática ou estratégica. Cada um tem suas próprias vantagens e desvantagens.

Mesmo com as modificações do software OO, ainda é difícil, não apenas a parte de codificação é difícil, mas o processo de promover uma mudança na produção em ambientes de reclamação (dado o estado atual da tecnologia) é irreal para grandes sistemas que deveriam ser trabalhando 24/7.

Sigo meu princípio que diz: " Quando possível, projete artefatos de software compartilhados estrategicamente " - Isso pode parecer que vai contra o princípio YAGNI de alguma forma; no entanto, essa é minha opinião. Essa abordagem garante menos retrabalho no custo da complexidade e dos recursos.

No seu caso, as atividades necessárias para adicionar uma nova tabela de junção incluiriam: design, aprovação do design, alteração do esquema, reescrita de vários métodos para CRUD para 3 tabelas (com exceção de algumas leituras), criação de índices, criação de GUI para o CRUD da nova tabela, para permitir que o usuário selecione as PKs na criação, atualização da nova tabela, etc. Ah, e a propósito, não esqueça de testes de unidade, testes de aceitação do usuário, testes de sistema e promoção de produção.

Se isso não for suficiente, o verdadeiro pesadelo vem da perda de informações. Se você não possuía a tabela de junções e decidiu capturar as datas em que a associação / separação entre um funcionário e um departamento ocorreu, não será possível preencher automaticamente a data na tabela de junções. Você precisa inseri-los manualmente (se você tiver os dados).

Portanto, é melhor prever isso desde o início.


Tudo é melhor prever desde o início.
91111 JeffO

0

Como Matthew disse acima, a refatoração / alteração de bancos de dados geralmente é mais envolvida em comparação com o software, pois o gerenciamento de dados também precisa ser levado em consideração. Existem técnicas que podem ajudar, por exemplo, a garantir que você tenha um conjunto apropriado de testes de unidade de banco de dados, desacoplar aplicativos clientes do esquema base usando uma 'API de banco de dados' - sprocs / visualizações etc.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.