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.
fonte
Respostas:
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 .
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte