Motivos para não armazenar arquivos no banco de dados

Infelizmente ainda é muito comum encontrar aplicações que usam o banco de dados para armazenar imagens ou arquivos binários em suas tabelas. Irei apresentar alguns motivos para que você não faça isso em seus próximos projetos e o que pode ser usado como alternativa.

Todos os testes foram realizados utilizando o PostgreSQL 14 em um container Docker em um MacBook Air M1 com 8gb de RAM

Estrutura do banco de dados usado para testes

Estrutura do banco de dados

Espaço utilizado por cada tabela (ambas com aproximadamente 400 registros)

Cada arquivo em um registro da tabela perfil possui aproximadamente 50MB.
Disco ocupado pelas tabelas

Desempenho

Vamos comparar alguns operações básicas em ambas as tabelas.

Inserção sem arquivo
Tempo para inserção de registro sem arquivo

Inserção com arquivo (50MB)
Tempo para inserção de registro com arquivo

Consultando 200 registros da tabela perfil_sem_arquivo obtendo todas as colunas
Tempo de consulta de 200 registros sem arquivo

Consultando 200 registros da tabela perfil sem incluir a coluna que armazena o binário
Tempo de consulta de 200 registros com arquivo mas sem incluir coluna com o binário

Consultando 1 registro na tabela perfil incluindo a coluna com o arquivo
Consultando um registro com a coluna que armazena o binário

Consultando 10 registros incluindo a coluna com o arquivo
Consultando 10 registros com arquivo

Removendo 394 registros com arquivo
Removendo 394 registros com arquivo

Removendo 393 registros sem arquivo
Removendo 393 registros sem arquivo

Como podemos ver, o banco de dados performa muito melhor na tabela que não armazena um arquivo em seus registros.

Financeiro

Vamos usar o Google Cloud SQL e o Cloud Storage como exemplo para entender o custos envolvidos.

Em Julho de 2022 a instância mais barata para utilizar o Cloud SQL é a db-f1-micro em Iowa (us-central1). O custo mensal seria aproximadamente $7.67 (R$ 40,90), a capacidade máxima seria de apenas 3.062 GB, fora o custo do uso de rede, vCPU e memória (que como mostrei nos exemplos anteriores, ao armazenar arquivos no banco esses recursos são mais exigidos e portanto teríamos um custo maior).

Utilizando um serviço como o Cloud Storage o nosso custo cai para $ 0,02 a cada GB por mês + preço de uso de rede + $ 0,05 a cada 10.000 operações.

Com esse serviço, ainda temos a possibilidade de reduzir o valor pago utilizando classes de armazenamento mais baratas (quanto mais barato for, menor é a disponibilidade do arquivo). Dependendo do tipo da aplicação que estamos lidando, esse pode ser um recurso interessante para otimizar os custos com cloud.

Infraestrutura e CDN

Disponibilizar esses arquivos via http exige que consultas sejam realizadas no banco de dados (que no nosso exemplo anterior já consumiria quase 5 segundos da requisição) , que o servidor baixe os dados vindos do banco (gerando mais custos com consumo de rede e ocupando mais memória das instâncias do backend) e o cliente baixe esse arquivo novamente. Além de obviamente aumentar muito o tempo da nossa requisição, ainda nos leva a possíveis problemas com os load balancers que são usados pela infraestrutura da aplicação.

Ao utilizar serviços que são voltados para o armazenamento de arquivos, abrimos a possibilidade para a utilização de CDNs para o cacheamento em diferentes regiões do mundo, possibilitando um download com latência menor (super importante para o carregamento de imagens em sua aplicação).

Em resumo

Não vale a pena sacrificar a escalabilidade da sua aplicação nesse nível. Prefira armazenar apenas URLs dos arquivos em seu banco de dados e faça o uso de um bom serviço de storage. Eu particularmente gosto bastante da AWS S3 e Google Cloud Storage.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *