Atualmente, estou criando um aplicativo da Web que permite aos usuários armazenar e compartilhar arquivos de 1 MB a 10 MB.
Parece-me que armazenar os arquivos em um banco de dados diminuirá significativamente o acesso ao banco de dados.
Será esta uma preocupação válida? É melhor armazenar os arquivos no sistema de arquivos e salvar o nome e o caminho do arquivo no banco de dados? Existem práticas recomendadas relacionadas ao armazenamento de arquivos ao trabalhar com um banco de dados?
Estou trabalhando em PHP e MySQL para este projeto, mas é o mesmo para a maioria dos ambientes ( Ruby on Rails , PHP , .NET ) e bancos de dados (MySQL, PostgreSQL ).
database
database-design
mysql
file-handling
B Seven
fonte
fonte
10MB
como grande em um sistema moderno.Respostas:
Razões a favor do armazenamento de arquivos no banco de dados:
Razão para armazenar arquivos no banco de dados:
FILESTREAM
objeto do SQL Server, e precisar migrar para um sistema de banco de dados diferente.Na IMO, considerar o armazenamento de arquivos no banco de dados ou não como "ruim" requer mais informações sobre as circunstâncias e os requisitos. O tamanho e / ou número de arquivos sempre serão pequenos? Não há planos para usar o armazenamento em nuvem? Os arquivos serão veiculados em um site ou em um executável binário como um aplicativo do Windows?
Em geral, minha experiência constatou que armazenar caminhos é mais barato para as empresas, mesmo levando em conta a falta de ACID e a possibilidade de órfãos. No entanto, isso não significa que a Internet não seja uma legião com histórias de falta de controle de ACIDs que dão errado no armazenamento de arquivos, mas significa que, em geral, essa solução é mais fácil de construir, entender e manter.
fonte
Em muitos casos, isso é uma má ideia. Ele inchará os arquivos do banco de dados e causará vários problemas de desempenho. Se você colocar os blobs em uma tabela com um grande número de colunas, é ainda pior.
Contudo! Alguns bancos de dados, como o SQL Server, têm um tipo de coluna FILESTREAM. Nesse caso, seus dados são realmente armazenados em um arquivo separado no servidor de banco de dados e apenas um ID para o arquivo é salvo na tabela. Nesse caso, não vejo muitas razões para não manter os dados no servidor SQL. Os arquivos são incluídos automaticamente como parte do backup do servidor, e o banco de dados e os arquivos nunca estão fora de sincronia. O problema com a sugestão de Tony de armazenar nomes de arquivos é que o banco de dados e o sistema de arquivos podem ficar fora de sincronia. O banco de dados alegará que um arquivo existe quando foi excluído no disco. Se um processo estiver modificando o banco de dados e depois travar, os arquivos e o banco de dados não corresponderão (ou seja, nenhum ACID com arquivos fora de um banco de dados).
fonte
Sim, é uma má prática.
Impacto no desempenho no banco de dados:
SELECT
com qualquer coluna BLOB, sempre fará um acesso ao disco, enquanto sem os BLOBs você terá a chance de obter dados diretamente da RAM (o banco de dados de alto rendimento será otimizado para ajustar as tabelas na RAM);Vantagem de velocidade - nenhuma ! Enquanto alguns sistemas de arquivos mais antigos não lidam bem com diretórios com milhões de arquivos, a maioria dos modernos não tem nenhum problema e, na verdade, usa o mesmo tipo de estrutura de dados que os BDs (geralmente árvores B). Por exemplo, ext4 (sistema de arquivos Linux padrão) usa Htree .
Conclusão: isso prejudicará o desempenho do seu banco de dados e não melhorará o desempenho da recuperação de arquivos.
Além disso, como você está falando sobre aplicativos da Web - servir arquivos estáticos diretamente do sistema de arquivos usando o servidor da web moderno, o que pode fazer o
sendfile()
syscall é uma tremenda melhoria de desempenho. Obviamente, isso não é possível se você estiver buscando arquivos do DB. Considere, por exemplo, esse benchmark , mostrando o Ngnix executando 25K req / s com 1000 conexões simultâneas em um laptop de baixo custo. Esse tipo de carga fritaria qualquer tipo de banco de dados.fonte
Eu seria pragmático e seguiria o princípio "não otimize ainda". Faça a solução que faz sentido no momento e uma que você tenha os recursos de desenvolvimento para implementar adequadamente. Existem muitos problemas em potencial . Mas esses não se tornam necessariamente problemas reais. Por exemplo, provavelmente não seria um problema se você tiver 100 usuários. Ele pode ser um problema se você tem 100.000 ou 10.000.000 usuários. Porém, no último caso, deve haver uma base para mais recursos de desenvolvimento para lidar com todos os problemas.
Mas armazenar os dados no banco de dados impede que você lide com outros problemas, por exemplo, onde os arquivos devem ser armazenados, como devem ser copiados, etc. Como você está escrevendo um aplicativo da Web, seria uma boa idéia por motivos de segurança. para garantir que o processo que hospeda o aplicativo não tenha acesso de gravação ao sistema de arquivos, você deve configurar o servidor para que o processo tenha acesso de leitura / gravação à pasta em que os dados estão armazenados.
Eu pessoalmente escolheria armazenar os dados no banco de dados, mas certifique-se de que os BLOBS não sejam lidos até que sejam realmente necessários, ou seja, nenhum "SELECT * FROM ..." executado nessas tabelas que contêm blogs. E eu me certificaria de que o design facilite a transferência dos dados do banco de dados para o sistema de arquivos, se você tiver problemas de desempenho. Por exemplo, armazene as informações do arquivo em uma tabela de arquivos separada , mantendo as informações do arquivo afastadas de outras entidades comerciais.
Supondo que você tenha uma classe File para representar um arquivo lido no banco de dados, o impacto da codificação da sua saída posterior será mínimo.
fonte
A Microsoft lançou um white paper sobre isso alguns anos atrás. Ele se concentra no SqlServer, mas você pode encontrar algumas informações interessantes:
Uma versão muito concisa de sua conclusão é:
Eu recomendaria que você escrevesse alguns pequenos testes para seu caso de uso específico. Lembre-se de que você deve tomar cuidado com os efeitos do cache. (Fiquei impressionado na primeira vez que obtive velocidades de salvamento em disco que pareciam ter taxas de transferência mais altas do que era fisicamente possível!)
fonte
A velha sabedoria convencional de armazenar arquivos fora do banco de dados pode não ser mais válida. Por uma questão de princípio, eu preferiria a integridade do que a velocidade e, com um DBMS moderno, você pode ter os dois.
Tom Kyte parece concordar :
fonte
Sim.
Se você enviar um arquivo do seu sistema de arquivos, seu servidor Web poderá usar código do kernel como sendfile () no BSD ou Linux para copiar o arquivo diretamente no soquete. É muito rápido e muito eficiente.
A entrega de arquivos fora do banco de dados significa que você deve copiar os dados do disco do servidor de banco de dados para a memória do servidor de banco de dados, da memória do servidor db para a porta de rede do servidor db e, em seguida, da rede para o processo do servidor da Web e depois para o diretório conexão de rede de saída.
A menos que você tenha realmente um bom motivo para isso, é sempre melhor servir arquivos estáticos do sistema de arquivos.
fonte
O famoso Tom Kyte escreveu que eles (o Oracle) estão usando o banco de dados Oracle como servidor de arquivos e está funcionando perfeitamente, ainda mais rápido que o sistema de arquivos normal, com transacionalidade total, sem perda de desempenho e com backup único.
Sim, mas observe que eles são os produtores do banco de dados Oracle e, para qualquer outro usuário, há problemas de custo. O uso de banco de dados comercial, como o Oracle, para armazenamento de arquivos é simplesmente ineficaz.
No entanto, com o PostgreSQL, por exemplo, você pode simplesmente executar outra instância de banco de dados apenas para armazenamento de blob. Você tem suporte transacional completo. Mas a transacionalidade custa espaço no banco de dados. É necessário que o banco de dados armazene várias instâncias de blob para várias transações simultâneas. No PostgreSQL, é o mais doloroso, pois esse banco de dados armazena as duplicatas dos blobs feitos para a transação, mesmo que não sejam mais necessários, até que o processo VACUUM seja concluído.
Com o armazenamento do sistema de arquivos, por outro lado, você deve ter muito cuidado quando alguém modifica o arquivo, porque a transação pode ser revertida e a cópia do arquivo deve ser mantida até que a versão antiga não esteja mais visível.
No sistema em que os arquivos são adicionados e excluídos apenas, e o acesso transacional aos arquivos não é um problema, o armazenamento do sistema de arquivos será IMHO a melhor opção.
fonte
Geralmente, é melhor armazenar BLOBs grandes em uma tabela separada e manter uma referência de chave estrangeira ao BLOB em sua tabela principal. Dessa forma, você ainda pode recuperar o arquivo do banco de dados (para não precisar de nenhum código especial) e evitar os problemas que envolvem as dependências externas do banco de dados (mantendo o banco de dados e o sistema de arquivos sincronizados, etc.), mas apenas incorre nessa sobrecarga. se você ingressar explicitamente nessa tabela (ou fazer uma chamada separada). 10 MB não é muito grande, a maioria dos bancos de dados comerciais modernos não terá problemas. A única razão pela qual eu armazenaria um arquivo no sistema de arquivos é reduzir a largura de banda do banco de dados. Se seu banco de dados embaralha muitos desses arquivos, talvez seja necessário dividir a carga de trabalho e armazenar apenas um descritor de arquivo de algum tipo. Em seguida, você pode ter uma chamada separada para carregar o arquivo de outro servidor,
fonte
Você pode ter alguns destes problemas:
SELECT *
que envolva a linha com o blob grande leva muito tempo, mesmo que você não precise do blob (é claro que você deve fazer uma seleção específica, mas às vezes os aplicativos são escritos assim)Claro que você também recebe alguns benefícios:
Pessoalmente, não faço isso porque acho os contras muito mais pesados que os profissionais. Mas, como mencionado acima, depende totalmente do seu caso de uso e tal.
fonte
Alguns sistemas de gerenciamento de conteúdo da Enterpirse, como o SiteCore, estão usando um banco de dados para armazenar dados da página e outro banco de dados para armazenar arquivos. Eles estão usando o MS SQL Server.
fonte
Para implementação prática, eis o que você pode interessar:
Benefícios:
Desvantagens:
fonte