Socoorro! JSON no banco de dados?
Fala devs,
estou em contato com um sistema onde os dados de retorno de uma api são armazenados dentro do db tem muitos json passando de 30MB de tamanho. Para contexto estamos falando de um banco de dados PostgreSQL com TB (Terabytes).
Dos grandes problemas as quedas do server e lentidão são normais.
Index já não são uma opção.
Na nossa área sempre tem um "depende" e eu ja usei um campo de texto para armazenar um json, (nao me orgulho disso) mas era o recurso disponível, tmb era outro contexto, totalmente diferente, e se tratava de um texto com no maximo 512 caracteres.
No contexto atual tem json de 120 MILHÕES de caracteres, não consigo me conformar com isso.
Então me ajudem a entender por favor.....
Isso é comum por ai? Tem vantagens técnicas nessa pratica? existe algum ganho válido? ou so estamos trocando o custo de lugar (storage x custo de processamento)? Existe algum video no tiktaka que apresenta uma solucão magica? (kkkk)
Na minha visão.. binarios deveriam ir para um storage (s3, azure blob, etc), estou equivocado?
me ajudem por favooooor...
Bem... depende.
Pode ter ganho, pode ser válido, mas não temos como saber. Só daria para dizer vendo o todo, cada detalhe, se aprofundando em tudo.
A chance maior é de isso ser um completo erro, mas é só um feeling que eu tenho vendo isso, eu não aposto nisso.
Só perguntando para quem fez quais foram as motivações. Se não tem como, e não consegue enxergar por conta própria, provavelmente ficará sem saber.
Esse tipo de coisa provavelmente foi feito porque quem só queria dar a solução. Queria uma solução "mágica". E por querer soluções mágicas que saem essas coisas. É muito comum isso ser fruto de falta de comprometimento com o que estava fazendo. Mas poderia ter uma justificativa boa.
O fato de não ter uma informação que demonstre porque é assim já é um indício que algo foi feito "nas coxas".
E para resolver precisaria de uma avaliação minusciosa de quem entende de banco de dados. Uma das soluções é abandonador tudo isso e apenas criar uma outra solução boa apreveitando os dados. Mas se for feito com o "mesmo capricho" desse, será só um novo problema.
Faz sentido para você?
Espero ter ajudado.
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).
De forma geral, e sem saber dos requisitos do sistema, eu costumo dizer que depende.
Mas neste caso específico, não consigo imaginar uma situação em que faça sentido ter um JSON com milhões de caracteres no banco.
Outro ponto confuso é que primeiro vc diz que são caracteres, mas depois menciona "binários". O que exatamente tem nesse JSON? Precisa estar tudo junto mesmo? Não tem como separar as informações em várias tabelas e só juntar na hora que precisa do JSON final?
Enfim, sem mais informações fica difícil opinar algo. Mas à primeira vista parece tudo muito estranho, e provavelmente não foi feito da melhor forma.
Vocês estão salvando o que em json para ter 120m de caracteres kkk e quando tempo leva para essa API responder com um retorno de 30MB.
E sim é recomedado guardar dados binarios em um cloud e não diretamente na consulta. Depois que guardar em um cloud, ai sim usar o arquivo, retornando do banco de dados a URL onde está hospedado o arquivo
Como não sei a natureza desses dados fica difícil dizer se faz sentido ou não. Porém, há uma abordagem que já utilizei que me ajudou a manter o banco saudável. O json, Eu salvava em um banco de chave-valor (era um Redis) e a chave, Eu enviava para o banco relacional para criar uma referência com meus dados. No seu caso, tu ainda poderia manter eles adicionalmente em um S3, para garantir maior durabilidade. Porém, fica a ressalva: Eu não tinha um cenário com objetos tão grandes, e talvez um banco de chave-valor sofra um pouco no seu caso.
Postgres tem API para Json. Acho que ela da seu jeito para otimizar as coisas! https://andrewrosario.medium.com/utilizando-json-no-postgresql-com-jsonb-data-types-3c4d10dd4ea3
Essa API nasce para competir com bancos não relacionais! Que usam Json ou algo parecido. E já é bem usada e comum. Agora o jeito que tudo esta salvo que diz como isso vai ficar lento ou rápido!
O Postgres tem funções de JSON, não sei qual o framework/orm que vocês estão usando, mas eu sei que no django tinha um JSONField que dava pra inclusive pegar o dado dentro do json usando as queries do ORM, tipo como um não relacional.
Mas no seu caso aí, tem que ver se os dados seguem um padrão que possa ser convertido em tabelas, senão acho que o jeito é usar um não relacional ou até um redis da vida, se não tiver necessidade de armazenar por muito tempo.
Cara, isso é pratica relativamente normal, e é possivel até pesquisar... Mas é certamente algo que a gente nunca vai ver como padrão.
Sugestão seria armazenar num s3 se não precisar fazer queries.
Algumas perguntas para refinar a resposta:
- Você está fazendo queries em cima desse JSON ou apenas armazenando e lendo de acordo com outros campos da tabela?
- O conteúdo integral desse JSON é realmente necessário, ou dá pra fazer uma sanitização, removendo partes inúteis?
- Se não
Não sei a estrutura do Banco de Dados e também os dados armazenados, mas falarei dos casos em que eu gosto de usar jsonb
em uma tabela:
- Quando eu preciso salvar dados auxilares de um registro que podem seguir um schema definido ou não e que eu não necessite realizar comsultas dentro deste campo, ou seja, são dados exclusivamente para visualização ou o processamento deles podem ser feitos no backend;
- Quando eu preciso fazer uma tabela de histórico dos dados, exemplo:
Tabela_Referencia | Registro_PK | Registro_Antigo | Novo_Registro | Acao | Data_Acao |
---|---|---|---|---|---|
usuario | 1 | {"nome": "Fulano"} | {"nome": "Fulano de Tal"} | update | 2023-07-02 |
No exemplo acima, temos uma tabela que mostra o histórico dos dados de todas as tabelas para fins de auditoria, o registro exemplificado contém uma atualização do campo nome do registro 1 da tabela de usuários.
Como eu mostro esses dados? Crio uma view materializada devidamente indexada com atualização periódica concurrently
e faço a query na própria view ou obrigo o usuário administrador à escolher um período, tabela de referência e um pk (mas é apresentado de forma amigável no front).
- Nunca armazene binário no Banco de Dados, nem que seja imagens de 30 kb, a boa prática é você salvar o arquivo em uma pasta no servidor ou utilizar um serviço de cloud storage, registrar o caminho relativo do arquivo (sem vazar essa informação para o front) ou a URL completa quando armazenado em um serviço externo.
Estes são os casos de uso que eu tenho experiência e consegui lembrar agora.
Você vai ler muitos dependes aqui, portanto vou traçar qbaixo um racional para resover as constantes quedas que tens hoje, ok?
A empresa precisa consultar todos estes TB de dados? Normalmente as empresas não precisam de mais de 3 anos de dados em seus bancos, valide com sua organização qual é janela maxima de consulta destes dados e... crie um backup da base e coloque num S3, apague os dados desnecessários. crie uma rotina automatizada para fazer este backup e expurgo de dados mensal ou trimestral. Sobre a coluna no banco com JSON, a pergunta é voce precisa mesmo disso dentro do banco? com que frequência voce consulta este dado? O que fazer com ele, tem umas ideias boas boas aqui como colocar o arquivo no s3 e guardar o caminho,acho deveras interessante, principalmente se você não tem necessidade de fazer nenhum tipo de consulta dentro deste json. Em caso de consultas pode usar o próprio postgress para te auxiliar, pode usar tabelas de extensão para guardar este dado e não deixar sua tabela principal pesada ou ate considerar o uso do mongobd para guardar estes json. Lembre-se de programar um expurgo para estes dados senao tu vai gastar muito com o tempo. Boa sorte
Se você não vai fazer query nesses dados (se está armazenando apenas como um log ou para permitir o download desse conteúdo no futuro), eu sugeriria ao time de armazenar em storage mesmo.
Acredito que a única vantagem que pode ter sido pensado quando criaram a coluna, é que pode ser mais prático manter o json (criar, atualizar e excluir) sem a necessidade de um código extra, e também bem provável por falta de conhecimento de outras abordagens.
Cara, eu criaria um esquema pra organizar e salvar no S3, e na tabela salvaria apenas o caminho do S3 em questão. Me parece a forma mais interessante.
Cria alguma coisa pra fazer essa migração, pode ser uma cron que faz parcelado.