Qual é a maneira mais fácil e eficiente de projetar um banco de dados? Do meu ponto de vista, há algumas opções para o design do armazenamento de dados de um aplicativo:
- Projete o banco de dados da melhor maneira possível antes de escrever qualquer código de aplicativo . Isso lhe dá a vantagem de ter uma estrutura de dados base para trabalhar. A desvantagem disso, na minha opinião, é que você terá muitas alterações como especificidades do aplicativo que afetam o que/onde/como das alterações de dados durante o ciclo de desenvolvimento do aplicativo.
- Projete o banco de dados à medida que o aplicativo se concretiza . Quando você precisa de alguns objetos de banco de dados enquanto escreve o aplicativo, você desenvolve o banco de dados paralelo (cronologicamente) ao aplicativo. As vantagens seriam menos alterações na estrutura do banco de dados, a meu ver. A desvantagem seria a divisão de tempo e esforço de desenvolvimento entre o código do aplicativo e o desenvolvimento do banco de dados.
Em sua experiência, qual você considera o método mais produtivo e eficiente?
Além de outras respostas...
Capturar seu modelo conceitual primeiro deve definir o escopo e os requisitos. A partir disso, você pode derivar seus modelos de dados lógicos e físicos.
Uma vez que isso é principalmente estático, você tem um banco de dados estável para construir seu aplicativo. Isso é contrário à sua primeira opção.
Seu segundo ponto terminará em uma bola de lama bagunçada e insustentável . O modelo de dados nunca será corrigido: se você não o projetou antecipadamente, não terá tempo de corrigi-lo antes do envio. Você estará muito ocupado hackeando coisas.
Pequenas alterações no esquema, combinação ou divisão de tabelas, alteração de relacionamentos, etc. acontecerão, mas em "ilhas" localizadas e seu modelo + design básico permanecerão inalterados.
Você terá dificuldade em encontrar qualquer departamento de software moderno que não esteja operando alguma variante do Agile. Os DBAs, em comparação, estão presos na idade das trevas, com o tipo de pensamento que a resposta de @RobPaller ainda contém lugar comum.
Modificar um esquema de banco de dados nunca foi tão fácil quanto modificar o código, e é por isso que houve relutância em adotar uma abordagem ágil para desenvolvimento e manutenção de banco de dados. Agora que temos as ferramentas e técnicas para operar de maneira semelhante aos desenvolvedores, definitivamente devemos. Só porque não é fácil mudar o esquema, não significa que você não possa e que não deva.
Não estou defendendo uma abordagem aleatória para o design do banco de dados (consulte os comentários), apenas uma abordagem que espelha mais de perto a de uma equipe de desenvolvimento ágil. Se você faz parte de um projeto ágil, não terá requisitos para trabalhos que podem ( ou não ) ocorrer no futuro, então projete para o que você sabe que é necessário, não para o que pode ser.
Acho que isso coloca meu voto na sua opção 2 e suspeito que posso me encontrar no frio nesta!
Tive o luxo de projetar vários bancos de dados de média complexidade, todos usados em empresas, com vários front-ends, incluindo web, Access e C#.
Normalmente, eu me sento e elaboro o esquema do banco de dados com antecedência. Isso sempre fez mais sentido para mim. No entanto, não houve um único caso em que eu não acabasse fazendo alterações, adicionando novas tabelas ou convivendo com aspectos que me incomodavam e basicamente demoravam a consertar.
Não acho que a cura seja escrever o código primeiro. E não acho que o problema seja "requisitos de negócios insuficientes" ou, pelo menos, não um que poderia ter sido totalmente resolvido. Os usuários não sabem o que precisam e eu não tenho o poder de fazê-los pensar mais ou ser mais inteligentes ou mais conscientes ou responder melhor às minhas perguntas. Ou eles discutem e eu recebo ordens para fazer algo de uma determinada maneira.
Os sistemas que construo geralmente estão em novas áreas nas quais ninguém entrou antes. Não tenho a adesão da organização, os recursos ou as ferramentas para fazer o tipo de trabalho que uma equipe de desenvolvimento de profissionais de design de alto nível poderia receber como equipe dez vezes mais do que eu ganho para construir coisas em duas vezes o tempo.
Eu sou BOM no que faço. Mas há apenas um de mim fazendo isso em um ambiente que "não faz desenvolvimento".
Dito isso, estou melhorando na descoberta de regras de negócios. E eu conheço uma espécie de terceira opção (que aprendi em uma conferência Agile Development Practices):
Antes de projetar o banco de dados e antes de escrever qualquer código, desenhe telas rudimentares mostrando como o aplicativo funcionará. Eles devem ser desenhados à mão para evitar que alguém comente sobre a fonte, tamanho ou dimensões - você deseja apenas função.
Com transparências e pedaços de papel, você pode trocar dentro e fora, ter uma pessoa como computador, dois usuários não técnicos no assunto (dois para que falem em voz alta) e uma pessoa lá como um facilitador que faz anotações e desenha os usuários sobre seus processos de pensamento e confusões. Os usuários "clicam", arrastam e escrevem em caixas, o "computador" atualiza a tela e todos podem experimentar o design. Você aprenderá coisas que não aprenderia de outra forma até o início do processo de desenvolvimento.
Talvez eu esteja me contradizendo - talvez seja a melhor descoberta de requisitos. Mas a ideia é projetar o aplicativo primeiro, sem escrever nenhum código. Comecei a fazer isso em pequena escala e está funcionando! Apesar dos problemas em meu ambiente, ele está me ajudando a projetar melhor o banco de dados desde o início. Aprendo que uma coluna deve ser movida para uma nova tabela pai porque existem vários tipos. Aprendo que a lista de trabalho tem que ter pedidos permanentes que não vêm do sistema integrado de pedidos. Eu aprendo todo tipo de coisa!
Na minha opinião, esta é uma grande vitória.
Seu modelo de dados lógicos deve capturar efetivamente os requisitos de negócios de seu aplicativo. Seu projeto de banco de dados físico deve ser baseado no modelo de dados lógico combinado com as mudanças necessárias que você, como DBA, sente serem necessárias para maximizar a eficiência de seu RDBMS.
Se você está descobrindo que precisa fazer várias alterações no design do banco de dados subjacente ao longo do ciclo de vida de desenvolvimento de software do seu aplicativo, isso indica duas coisas:
Dito isso, uma vez que um aplicativo foi colocado em produção, não é incomum ter que voltar e fazer alterações iterativas no modelo de dados para dar suporte à evolução natural do aplicativo ou dos processos de negócios subjacentes.
Espero que isto ajude.
Para a maioria das finalidades, eu escolheria a Opção 2: Construir o banco de dados em paralelo com os outros componentes. Sempre que possível, adote uma abordagem iterativa e forneça funcionalidade de ponta a ponta conforme você cria cada peça.
Isso requer uma certa quantidade de disciplina de projeto. Aplique a normalização rigorosamente (Boyce-Codd / Fifth Normal Form) sempre que alterar o banco de dados para manter a qualidade e não acabar com um modelo ad hoc e inconsistente. Seja o mais agressivo possível com regras de negócios e restrições de banco de dados de atendimento. Em caso de dúvida, é melhor aplicar uma restrição antecipadamente - você sempre pode retirá-la mais tarde. Seja inteligente sobre a ordem de implementação dos componentes arquitetônicos para minimizar a dívida técnica. Tenha um bom conjunto de diretrizes de design de banco de dados que toda a equipe de desenvolvimento compre.
É claro que tudo isso precisa andar de mãos dadas com outras boas práticas de engenharia de desenvolvimento: integração contínua, automação de teste e, principalmente, da perspectiva do banco de dados, criação de dados de teste. A criação de dados de teste de dados dimensionados de forma realista deve ser feita em cada iteração sem falhas.
No mundo da arquitetura, a frase "A forma segue a função" foi cunhada e posteriormente adotada na construção de edifícios altos. O mesmo deve ser aplicado à infraestrutura de banco de dados e ao desenvolvimento de aplicativos.
Imagine escrever um aplicativo, decidindo instantaneamente que você precisa de uma mesa aqui e outra ali. Quando seu aplicativo é concluído, você tem um grande número de tabelas sendo tratadas como arrays. Olhando para todas as tabelas lado a lado, as tabelas definitivamente parecerão não ter rima ou razão.
Infelizmente, algumas lojas de desenvolvedores pegam algo como memcached, carregam-no com dados na RAM (tratando-o assim como um canal de dados) e fazem com que um banco de dados, como MySQL ou PostgreSQL, se comporte simplesmente como uma unidade de armazenamento de dados.
O incentivo para usar um banco de dados deve ser olhá-lo adequadamente: como um RDBMS. Sim, um Sistema de Gerenciamento de Banco de Dados Relacional . Quando você usa um RDBMS, seu objetivo inicial não deve ser apenas estabelecer tabelas para armazenamento, mas também para recuperação. As relações entre as tabelas devem ser modeladas de acordo com os dados que você deseja ver e como eles são apresentados. Isso deve ser baseado na coesão e integridade dos dados, juntamente com regras de negócios conhecidas. Essas regras de negócios podem ser codificadas em seu aplicativo (Perl, Python, Ruby, Java, etc) ou no banco de dados .
CONCLUSÃO
Eu definitivamente escolheria a opção 1. É preciso planejamento adequado, modelagem de dados e análise contínua de dados. No entanto, isso deve minimizar as alterações no banco de dados a longo prazo.
Tenho em mente a seguinte regra: "você só pode obter do banco de dados as informações que você tem dados para gerar". Então, eu desenho primeiro o banco de dados depois o código.
Por quê? Não importa qual metodologia/linguagem/conjunto de ferramentas eu use, se todos os dados relevantes forem bem projetados e armazenados no banco de dados, posso recuperá-los. Não importa se é em C#/Delphi/FORTRAN/COBOL/Assembly/VBA ou Crystal Reports; OO projetado ou orientado a eventos/dados/qualquer coisa; ágil ou cascata. Se os dados estiverem lá, posso recuperá-los se as ferramentas que uso puderem se conectar ao banco de dados. Posso criar os relatórios de vendas se puder SELECIONAR os pedidos para as receitas do trimestre - mesmo que tenha que escrevê-los byte a byte na montagem.
Se os dados relevantes não estiverem lá ou mesmo se estiverem, mas (des) estruturados de forma que não consiga recuperar as informações de que preciso - como codificá-los?
Acho que isso deve ser feito antes que haja qualquer código real para o aplicativo, mas não antes que o aplicativo seja projetado.
Meu fluxo de trabalho típico, se estiver trabalhando sozinho, é:
Como frequentemente trabalho em equipe e estamos geograficamente dispersos (e em vários fusos horários), tendemos a fazer uma reunião inicial:
Em seguida, voltamos para casa, escrevemos nossa parte e, se um componente precisar de seu próprio armazenamento local, desde que o mantenedor dessa parte mantenha a API consistente para seu módulo. O armazenamento de dados principal é tratado como um módulo com sua própria API, e espera-se que as pessoas escrevam nele. (nos casos em que a velocidade do banco de dados é crítica, a API é a tabela de definições e, se houver alterações, usamos views ou algum outro mecanismo para apresentar a versão anterior até que todos os módulos possam ser atualizados)
Como sempre, depende ;)
Por exemplo, suponha que temos um protótipo de trabalho de tamanho pequeno desenvolvido em Python e usando arquivos simples, e os usuários estão satisfeitos com os recursos do protótipo, então tudo o que precisamos fazer é colocá-lo em produção, usando RDBMS como back-end . Quando este for o caso, é razoável esperar fazer certo da primeira vez - o problema é pequeno e bem definido. Nesses casos, projetar antecipadamente é viável.
Por outro lado, quando estamos descobrindo os requisitos em um ambiente Agile, precisamos de algumas iterações para entendê-los melhor. Nessas situações, o banco de dados evolui com o restante do aplicativo. Isso é o que costumamos fazer. Como podemos refatorar tabelas OLTP ao vivo sem qualquer tempo de inatividade e com baixo risco, estamos confortáveis com a possibilidade de refatorações de banco de dados.