Rails - usar ou não STI ... eis a questão

8

Seis meses atrás, fiz uma pergunta sobre modelagem de dados para o meu aplicativo e recebi alguns conselhos apontando-me para a STI (consulte Modelo de dados Rails - pergunta sobre melhores práticas para obter detalhes).

Eu brinquei com ele, fiz funcionar um pouco, depois me distraí e coloquei o projeto em hiato.

Comecei a desenvolvê-lo novamente do zero, com o benefício de mais 6 meses de experiência em programação / ROR, e mais uma vez bati nessa barreira quando se trata de modelar ingredientes para minhas receitas de cerveja.

Para dar um resumo rápido, suponha que eu tenha três tipos de ingredientes (malte, lúpulo e fermento) - cada um compartilha alguns atributos (nome, preço, fornecedor), mas cada um também possui atributos específicos para esse tipo de ingrediente. Eles são todos relacionados (todos são ingredientes), mas têm um "comportamento" diferente (por exemplo, os grãos são amassados ​​e haveria lógica para lidar com o que não se aplicaria ao lúpulo / levedura, etc ...)

Os ingredientes são diferentes o suficiente para que eu esteja pensando em ter três tabelas separadas no banco de dados ... mas e os controladores? Posso usar um único controlador de ingredientes para gerenciar os modelos separados?

Eu li sobre alternativas ao STI (herança de tabela de classes e herança de várias tabelas), mas todas as soluções parecem esquisitas. Existem alternativas que me proporcionam a conveniência da STI (como obter todos os ingredientes, independentemente do tipo, com uma única consulta de tabela) sem os inconvenientes (campos nulos, tabelas difíceis de usar quando você continua adicionando subclasses e campos, etc.)

Desculpe, eu sei que esta pergunta é um pouco confusa, mas sinto que não consigo encontrar uma solução limpa e agora estou tentando descobrir qual método existe o mal menor. Tenho certeza de que outras pessoas já lidaram com isso, e eu adoraria ouvir os prós / contras de diferentes soluções. Obrigado!

Jim
fonte
2
Impossível responder, a menos que você publique código. Se você não sabe, basta escolher um e ver como vai. Você está escrevendo código Ruby, então por que se preocupar tanto com o que está acontecendo no banco de dados? Você sempre pode alterar o mapeamento posteriormente. Não parece que você terá um grande banco de dados em produção em breve.
Kevin cline
Eu diria que eles são todos os ingredientes e executam a lógica de negócios mais acima, mas sou apenas eu ... e como @kevincline diz que você pode mudar isso mais tarde. Uma vez que soam como a mesma mesa, essencialmente, nem seria difícil.
Rig
Eu acho que eu odeio a idéia de ter campos anuláveis em minha mesa, mas talvez eu só preciso superar isso ...
Jim

Respostas:

7

Embora os campos permanentemente nulos e as grandes tabelas pesadas sejam conceitualmente feias, elas geralmente não causam nenhuma ineficiência real. O espaço extra usado pelos campos nulos não é uma consideração importante para a maioria dos sistemas e a velocidade da consulta não será mais lenta se você configurar bem seus índices.

E os benefícios do STI geralmente valem a pena (eficiência do banco de dados minimizando junções e simplicidade de código compartilhada e DRYness). Portanto, se você usar um sistema SQL tradicional, aprenda a ignorar a feiúra conceitual e use a STI. Seu caso de uso é para o que a STI foi projetada.

Dito isto, se você não estiver muito aprofundado em seu ciclo de desenvolvimento para que este projeto seja anexado ao seu sistema de banco de dados (e parece que você não está), e estiver disposto a investir algum tempo em pesquisa / aprendizado, você realmente poderá deseja considerar uma alternativa ao SQL (existem muitas boas por aí). Atualmente, a alternativa mais popular (e minha favorita) é o MongoDB .

O MongoDB é baseado em documentos e não em esquema. Isso significa que não é tão rígido quanto ao que pode ser armazenado nele. Como o MongoDB não possui um esquema estruturado imposto, em seu projeto você pode apenas ter uma única coleção de ingredients("coleções" no MongoDB são semelhantes a "tabelas" nos bancos de dados SQL). Cada um ingredientnesta coleção poderia ter campos compartilhados, conforme definido em uma Ingredientsuperclasse (esses campos não seriam definidos no próprio banco de dados). E as subclasses Malt, Hopse Yeastpoderiam ter seus próprios campos individualizadas (novamente, conforme definido directamente nessas subclasses modelo, não no próprio db). É exatamente isso que você está procurando - ele oferece toda a comodidade da IST sem a sua feiúra conceitual.

Bônus adicional: você pode achar que usar um sistema de banco de dados NoSQL como esse ajudará a simplificar outras áreas do seu aplicativo. Em muitos (mais?) Domínios de negócios da Web comuns, o NoSQL é uma escolha melhor que o SQL, porque os domínios da Web tendem a ser particularmente intensivos em documentos (portanto, os documentos são uma escolha natural para o mecanismo de armazenamento).

Resumo: se você está interessado em usar um banco de dados SQL por causa da administração ou de alguma parte do seu aplicativo, ou se não tiver tempo para investir em aprender algo novo, basta usar o STI. Se você não está apegado ao uso de um banco de dados SQL e tem tempo para aprender algo novo, eu recomendo mudar para o MongoDB ou outro banco de dados NoSQL baseado em documento.

Ben Lee
fonte
Eu amo essa resposta. Aconselhamento prático para minha situação com o bônus adicional de alguns conselhos para facilitar as coisas no futuro. Ainda não verifiquei os bancos de dados NoSQL, mas vou investigar o MongoDB - parece bom, e como todo esse projeto é realmente uma experiência de aprendizado, estou definitivamente aberto a tentar coisas novas.
27412 Jim