Executando verificação de segurança...
4

Vamos discutir sobre JSON em colunas de bancos relacionais, mais precisamente em MySQL

Olá a todos, boa tarde!

Estou com algumas dúvidas, estou estruturando um sistema que inclusive a solução mais "correta" seria estabelecer uma relação many-to-many (criando uma tabela intermediária), mas pensei na possibilidade de adicionar uma única coluna numa tabela já existente e mudar a coluna para JSON para colocar um array de IDs ou alguma outra informação e queria saber se vocês já fizeram isso e quais prós e contras vocês julgariam?

Carregando publicação patrocinada...
2

A solução mais correta é sempre aquela que funciona melhor dentro de um dado contexto. Para ser correta em primeiro lugar tem que ter todos os requisitos levantados, e de forma correta. Não existe solução correta quando a entrada de dados é errada.

Um dos maiores desafios, e que parece ser muito grande para quem é inexperiente, é achar esses requisitos adequadamente.

Uma das questões a serem levantadas é saber se você precisa da informação independente ou não. Se ela é independente você deveria adotar uma entidade separada e fazer um relacionamento. Isso vale para o MySQL, SQLite, PostgreSQL, SQL Server ou até mesmo o MongoDB.

Se precisa disso, o MongoDB é bem pouco adequado para fazer, mas muita gente faz assim mesmo. Em alguns casos não adotam isso para não ficar inadequado no MongoDB, aí ela modela errado para se adaptar à tecnologia. Não farei maiores comentários, cada um entenda como quer.

Se o dado é dependente e tem uma ligação forte com uma entidade, então provavelmente ele deveria estar vinculado à entidade principal. No passado faziam separado porque a ferramenta não era tão boa, não tinha um jeito fácil de fazer isso. Hoje tem. Alguns SGDBRs mais que outros. O MySQL é razoável e pode ser com JSON.

Dá para dizer que para isso nem sempre o MySQL é o mais adequado, mesmo resolvendo razoavelmente bem. Mas os problemas são híbridos e em algumas entidades precisa mais da composição e outros mais a associação ou ainda a agregação. Como o banco de dados relacional trata bem ou razoavelmente bem ambas situações, ele costuma ser mais adequado, enquanto um modelo de documento só costuma se dar bem quando quase todo o modelo seja de dados dependentes ou completamente independentes sem relacionamentos.

Como em qualquer uso, não basta escolher usar, tem que aprender usar, e todas as formas têem seus desafios, escolher o que usar é a pontinha do iceberg. Pode adotar algo certo e fazer errado, aí parece que foi a escolha errada.

Para entender um pouco mais os termos.

Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

1

Baseado apenas no que você escreveu, não dá pra entender 100% a realidade do seu código. Porém, criar uma coluna a mais na tabela X para receber uma array de Ids, invés de criar uma coluna nova (que é o comum numa relação many-to-many), pode te dar mais trabalho em alguns outros pontos.
Por exemplo seus selects de dados sem filtro de ID, ou qualquer ação na tabela Y que não receberá os Ids relacionais da tabela X.. enfim.
Acabaria que muito desse tratamento iria sobrar para o backend executar, o que pode parecer irrelevante em códigos pequenos, mas custoso para códigos maiores.

1

Pros:

  • Mais simples de implementar

Contra:

  • Não vai conseguir utilizar as funcionalidades de um Banco relacional, como por exemplo indexar os Ids do JSON no mesmo nível de indexação que uma Primary Key teria.
  • Pode acabar ficando mais lento por que toda vez que você quiser buscar 1 valor dentro do array vai ter que acabar lendo o array inteiro.
  • Dificil de extender, caso tu quisesse colocar mais campos dentro desse array vai tornar seu JSON mais pesado, e como sempre vai ter que carregar tudo junto invéz de fazer um SELECT Field1, Field2 ...
  • Vai ter que tratar o JSON do lado do backend, recomendo criar depois uma camada de abstração ao seu repositório de dados para reduzir o acoplamento.

Enfim, como você mesmo disse a forma "correta" seria M:M então melhor fazer assim. Uma solução séria vc orientar seu sistema ao Domínio fazendo um code-first e dps deixar o ORM se virar pra implementar o banco, com certeza ele vai otimizar tudo e fazer a parte "chata" para você.
Numa arquitetura DDD você estrutura os dados orientados ao negôcio invés de orientar a ferramentas/dados, depois basta criar uma camada de abstração para converter isso para o banco o que vai até te permitir mudar de banco depois se quiser.

Então o que eu te recomendaria seria estruturar o teu sistema voltado ao negôcio e aos requisitos da sua app, invés de ficar quebrando cabeça com modelo relacional, claro que vai precisar converter isso pro SQL depois mas como eu disse, tem muitas ferramentas que já te fazem isso e também vai sempre pela forma "correta". Particularmente eu não curto muito ficar usando JSON, Files, Tabela para fazer Queue nem mesmo guardando Base64 dentro de banco relacional, não foram feitos para isso. É a forma mais "fácil" porém dependendo do âmbito do sistema vai ser um gargalo dps.

1

"Correto" depende muito de cada caso.

Mas de forma geral, um modelo relacional "clássico" (ou seja, sem JSON/XML/qualquer outro formato, sem NoSQL, etc) costuma funcionar bem para a maioria dos casos.

Dito isso, e sem saber mais detalhes do seu projeto (requisitos, tabelas já existentes, etc), é o que dá pra dizer (o restante já foi bem explicado nos outros comentários).

1

vou expor a dificuldade que eu tive ao fazer algo semelhante. estou criando um projeto que usa um DB postgreSQL, porem criei tabelas que salvam dados em uma coluna json, assim tenho a liberdade de mudar estrutura dos dados com mais liberdade
POREM....
dependendo da complexidade do json, isso cria algumas dificuldades a mais no projeto.
a maior dificuldade que enfrento é na hora de lidar com o json dentro das funçoes e "garantir" que ele vai estar correto e com as chaves:valores em seus devidos lugares.
dependendo da logica voce pode acabar reescrevendo o json sem querer com chaves e valores diferentes ou em posiçoes incorretas, então voce acaba precisando criar funções de "sanitização" do json pra evitar esses problemas.

outro problema é que vc fica sem parte das funcionalidades de query SQL que os DBs relacionais fornecem.

comecei fazendo uso e json mas em alguns casos to repensando isso e planejando usar tabelas comuns com os dados fixos mesmo

json é otimo quando vc ta criando o projeto e nao quer ter que ficar mudando o db a cada nova ideia, mas pode se tornar tao complexo que vai prejudicar a forma como voce lida com os dados.