Qual é o melhor local para armazenar arquivos binários relacionados aos dados no seu banco de dados? Você deveria:
- Armazenar no banco de dados com um blob
- Armazenar no sistema de arquivos com um link no banco de dados
- Armazene no sistema de arquivos, mas renomeie para um hash do conteúdo e armazene o hash no banco de dados
- Algo em que não pensei
As vantagens de (1) são (entre outras) que a atomicidade das transações é preservada. O custo é que você pode aumentar drasticamente os requisitos de armazenamento (e streaming / backup associado)
O objetivo de (3) é preservar a atomicidade em algum grau - se você pode garantir que o sistema de arquivos no qual você está gravando não permita que arquivos sejam alterados ou excluídos e sempre tenha o hash correto como nome de arquivo. A idéia seria gravar o arquivo no sistema de arquivos antes de permitir a inserção / atualização referente ao hash - se essa transação falhar após a gravação do sistema de arquivos, mas antes do DML do banco de dados, tudo bem, porque o sistema de arquivos está 'fingindo' sendo o repositório de todos possíveis arquivos e hashes - não importa se existem alguns arquivos que não estão sendo apontados (e você pode limpá-los periodicamente se for cuidadoso)
EDITAR:
Parece que alguns RDBMSs têm isso coberto de maneira individual - eu estaria interessado em saber como os outros fazem isso - e particularmente em uma solução para o postgres
fonte
Respostas:
Armazenar no banco de dados com um blob
Uma desvantagem é que ele torna os arquivos do banco de dados muito grandes e possivelmente muito grandes para fazer backup com a configuração existente. Uma vantagem é integridade e atomicidade.
Armazenar no sistema de arquivos com um link no banco de dados
Me deparei com desastres tão horríveis fazendo isso, e me assusta que as pessoas continuem sugerindo isso. Alguns dos desastres incluem:
C:\
caminho até a.doc
versão e nem todas as versões do NT foram capazes de lidar com caminhos longos.Armazene no sistema de arquivos, mas renomeie para um hash do conteúdo e armazene o hash no banco de dados
O último local em que trabalhei fez isso com base na minha explicação dos cenários acima. Eles pensaram que era um compromisso entre a incapacidade da organização de obter experiência com grandes bancos de dados (qualquer coisa maior que cerca de 40G foi ordenada como "muito grande"), a incapacidade corporativa de comprar discos rígidos grandes e a incapacidade de comprar uma parte traseira mais moderna solução e a necessidade de se afastar dos riscos 1 e 3 identificados acima.
Minha opinião é que armazenar no banco de dados como um blob é uma solução melhor e mais escalável em um cenário de vários servidores, especialmente com preocupações de failover e disponibilidade.
fonte
Número 1 para integridade completa dos dados. Use as outras opções se você não se importa com a qualidade dos dados. É simples assim.
A maioria dos RDBMS possui otimizações para armazenar BLOBs (por exemplo, SQL Server Filestream) de qualquer maneira
fonte
Se for para o oracle, dê uma olhada em dbfs e Secure Files.
O Secure Files diz tudo, mantenha TODOS os seus dados em segurança no banco de dados. É organizado em lobs. Arquivos Seguros é uma versão modernizada de lobs, que deve ser ativada.
O dbfs é um sistema de arquivos no banco de dados. Você pode montá-lo semelhante, como um sistema de arquivos de rede, em um host Linux. É realmente poderoso. Veja o blog Ele também possui muitas opções para ajustar-se às suas necessidades específicas. Sendo um dba, considerando um sistema de arquivos (baseado no banco de dados, montado no Linux), criei um banco de dados Oracle sem problemas. (um banco de dados, armazenado em um ... banco de dados). Não que isso seja muito útil, mas mostra o poder.
Mais vantagens são: disponibilidade, backup, recuperação, todas lidas de maneira consistente com os outros dados relacionais.
Às vezes, o tamanho é dado como uma razão para não armazenar documentos no banco de dados. Provavelmente, é necessário fazer backup desses dados para que não seja um bom motivo para não armazenar no banco de dados. Especialmente em uma situação em que documentos antigos devem ser considerados somente leitura, é fácil tornar grandes partes do banco de dados somente leitura. Nesse caso, essas partes do banco de dados não precisam mais de um backup frequente.
Uma referência em uma tabela a algo fora do banco de dados não é segura. Pode ser manipulado, é difícil de verificar e pode se perder facilmente. E as transações? O banco de dados oferece soluções para todos esses problemas. Com o Oracle DBFS, você pode fornecer seus documentos para aplicativos que não são de banco de dados e eles nem saberiam que estão cutucando um banco de dados.
Uma última e grande surpresa, o desempenho de um sistema de arquivos dbfs geralmente é melhor do que um sistema de arquivos comum. Isto é especialmente verdade se os arquivos forem maiores que alguns blocos.
fonte
Acho que a resposta certa aqui depende muito da sua inscrição e da importância desses documentos.
Para um sistema de gerenciamento de documentos, ou um sistema em que a capacidade de recuperação dos documentos armazenados é crítica (principalmente financeira, RH ou CRM), armazenar documentos em linha ou usar a tecnologia de documentos proprietários do seu fornecedor de DB favorito parece a coisa certa a fazer.
No entanto, existem muitas aplicações em que acredito que a decisão oposta é apropriada.
Sistemas de suporte técnico e sistemas do tipo wiki são aqueles em que acho que faz muito sentido manter os dados fora do banco de dados. Acredito que alguns, como Jira, realmente oferecem uma opção para escolher se você deseja armazenar documentos em linha ou não.
Para uma empresa de médio porte, armazenar documentos para um sistema de emissão de bilhetes em linha pode significar a diferença entre um backup compactado medido em megabytes e um medido em gigabytes.
Pessoalmente, eu preferiria colocar um sistema de venda on-line em alguns minutos e lutar com os documentos (geralmente menos importantes) por algumas horas, do que aumentar minha RTO "está quebrado e o CTO está respirando no meu pescoço", tendo que restaurar e reproduzir os logs de um backup muito maior.
Existem outros benefícios de manter os documentos separados.
Eu acho que uma combinação híbrida de # 2 e # 3 pode ser inteligente. Mantenha os nomes de arquivos originais, mas calcule e armazene um hash / soma de verificação do documento, para que você tenha algum ponto de referência que ajude a recuperação no caso de alguém mover ou renomear o arquivo.
Armazenar os arquivos com seus nomes de arquivos originais significa que os aplicativos podem literalmente puxá-los diretamente de um sistema de arquivos e enviá-los pela rede, ou em um mundo de clientes espessos, talvez até aponte o usuário diretamente para o servidor de arquivos.
fonte
Não faça isso.
Realmente não há uma vantagem de ter arquivos armazenados no banco de dados.
Já não parece estranho e suspeito quando você pensa:
Melhor ainda, diga em voz alta.
Sobre os fatos:
Usando o banco de dados
" PROS " ... mas não exatamente :
Eu realmente não quero ser tendencioso, mas acho que não há mais a acrescentar. Os profissionais não são realmente bons se você pensar sobre isso.
Se eu esqueci algo comentar abaixo, enquanto isso continue lendo abaixo.
CONTRAS:
Usando o sistema de arquivos
PROS:
CONTRAS :
* Impressão fina
Agora você está se perguntando, espere, significa que não há contras ?! Por quê?
Os maiores erros aqui é que as pessoas estão tentando estragar um parafuso com um martelo.
O principal motivo e eu diria até agora que o único motivo está sendo solicitado é por causa dos links dos arquivos .
Esse é um problema que o banco de dados não pretende solucionar. Até parece bobagem se você pensar sobre isso.
Quando, na realidade, logicamente o aplicativo deve realmente ser responsável pelo tratamento e veiculação de links.
Uma solução:
Isso também abstrai os caminhos nativos, torna o aplicativo mais portátil, sustentável e permite alternar para qualquer tipo de sistema de arquivos sem quebrar nada.
Quanto a como implementá-lo, está além do escopo desta resposta, mas você pode dar uma olhada em um exemplo geral, sem dúvida a linguagem da web (PHP) mais usada:
https://github.com/symfony/Routing
https://github.com/kriswallsmith/assetic
Ambos juntos são realmente poderosos.
fonte
Quero adicionar minha experiência aqui quanto às vantagens e desvantagens. No PostgreSQL, pelo menos, os impactos no desempenho são bastante mínimos em termos de servidor db. Blobs grandes são armazenados em arquivos separados, não nas tabelas de heap principal, a fim de afastá-los das operações que podem contar com um grande número de registros. Outros dbs podem fazer algo semelhante.
A principal vantagem é a capacidade de manter todos os dados relacionados em um único local para fins de atomicidade e backup. Isso reduz muito a chance de algo dar errado.
A principal desvantagem não é a que eu já vi abordada acima, e é o uso de memória no front-end. Eu não sei exatamente como cada banco de dados lida com isso, portanto isso pode depender da implementação, mas para o PostgreSQL, os dados são inseridos como uma string ASCII de escape (possivelmente hexadecimal, possivelmente com escapes embutidos). Isso deve ser convertido novamente em binário no front end. Muitas estruturas que vi para fazer isso envolvem a passagem do valor (não como referência) e a construção de uma nova string binária com base nele. Calculei que usar Perl para fazer isso acabou usando muitas vezes a memória do binário original para realizar.
Veredicto: Se os arquivos estiverem sendo acessados apenas ocasionalmente, eu os armazenarei no banco de dados. Se eles estão sendo acessados com frequência e repetidamente, pelo menos com o PostgreSQL, acho que os custos superam os benefícios.
fonte
Naquela época, a Microsoft aumentava a capacidade de armazenar imagens (e tipos de dados de blob semelhantes) no banco de dados. Esse foi um novo recurso interessante do SQL Server 2000 (tenho certeza de que era 2000, não 7.0) e muitas pessoas entraram na onda.
Armazenar BLOBS no banco de dados tem vantagens e desvantagens:
Por um lado, todos os seus dados e imagens ou documentos relacionados podem ser armazenados e acessados em um só lugar. O usuário do aplicativo não requer permissões de rede especiais, pois é o SQL que está servindo as imagens / arquivos / documentos.
Por outro lado, seu banco de dados pode crescer bastante, dependendo do tamanho e do número de BLOBS que você está armazenando. Isso afeta backups, requisitos de armazenamento, operações de recuperação sensíveis ao tempo, etc.
O SQL Server 2008 introduziu o streaming de arquivos. O banco de dados contém ponteiros para os arquivos, os arquivos residem no servidor e não no banco de dados, mas quando você faz backup do banco de dados, os arquivos também são copiados.
Seus backups podem ficar muito grandes, mas você não acaba com arquivos / documentos / blobs / imagens órfãos.
Minha preferência pessoal foi permitir que o banco de dados armazene ponteiros / locais de rede e permita que um servidor de arquivos lide com os arquivos. Os servidores de arquivos são melhor otimizados para essas tarefas de qualquer maneira.
fonte
SELECT image FROM table
no SSMS e valida se a imagem certa está lá?Não armazene arquivos em um banco de dados.
Todos, sem exceção, que podem executar qualquer RDBMS no mercado já possuem um banco de dados especificamente para armazenar arquivos, e o próprio RDBMS está usando-o! Esse banco de dados é o sistema de arquivos . Agora, vamos falar sobre algumas das possíveis desvantagens de armazenar arquivos no banco de dados, bem como alguns fatores atenuantes específicos para armazenar arquivos no banco de dados.
Nenhum arquivo de mãos para arquivos no banco de dados. O que isto significa?
Conversa do programador: você NÃO PODE procurar (
fseek
), não há capacidade de gerenciar o recurso com acesso assíncrono (asyncio
ouepoll
), não existesendfile
(economizando a cópia do espaço do kernel).Aplicação prática: deseja enviar um vídeo ou imagem para um cliente por HTTP2 / 3? Se estiver no banco de dados, primeiro será necessário consultá-lo. Para qualquer consulta que retorne esse arquivo, você precisará aguardar a conclusão de toda a consulta antes que o arquivo possa passar para a próxima etapa. Em uma instalação de produção com um rdbms em um servidor diferente do servidor da web, primeiro é necessário transferir o arquivo inteiramente do rdbms para o servidor da web, em vez de transmiti-lo. No entanto, se a camada de transporte fornecer abstração do sistema de arquivos (que até o NFS suporta), você poderá procurar no meio do arquivo e começar imediatamente a transmiti-lo de volta ao cliente sem armazenar em buffer mais do que o necessário. Isso é feito rotineiramente pelo servidor da webnginx , Apache , PureFTP e ProFTP.
Cópia dupla no RDBMS. Pelo fato de estar no banco de dados, você provavelmente o escreverá duas vezes. Uma vez em um log write-ahead (WAL) e, em seguida, novamente no espaço de tabela.
Nenhuma atualização, sempre o MVCC significa que nada é atualizado, apenas copiado novamente com as modificações e a linha antiga é marcada como expirada (excluída). Qualquer atualização no arquivo exigirá a gravação de toda a linha , não apenas o arquivo da linha inteira. Os sistemas de arquivos também podem fornecer isso, com registro no diário de dados, mas você raramente precisa disso.
Leitura e transferência de arquivo para diminuir a velocidade da consulta Se o arquivo em si estiver armazenado em uma linha que você precisa consultar, a linha inteira precisará aguardar a transferência do arquivo ou será necessário emitir duas consultas separadas .
Uso de memória no cliente DB. O cliente de banco de dados (libpq, jdbc, odbc, freetds, etc) ou similar provavelmente armazenará em buffer a consulta na memória. Quando esse buffer na memória estiver esgotado, ele poderá iniciar um buffer de disco ou, pior ainda, voltar ao kernel para ser paginado no disco.
A otimização de consultas em muitos bancos de dados fornece a capacidade de eliminar e colher consultas quando elas levam muito tempo ou recursos. Lembre-se de que as transferências de arquivos não serão especificadas em nenhuma implementação. Essa consulta foi interrompida após 3 segundos? Ou demorou 1 segundo e o back-end passou 2 segundos transferindo um arquivo? Não apenas "discriminado", como você declarará efetivamente quanto tempo uma consulta deve levar quando 99,9% das consultas retornarem 1 KB e a outra retornar 1 GB?
Sem cópia na gravação ou desduplicação O XFS e o BTRFS suportam a cópia na gravação e a desduplicação de forma transparente. Isso significa que ter a mesma imagem em qualquer lugar ou precisar de uma segunda cópia dela pode ser tratada de forma transparente pelo sistema de arquivos. No entanto, se o arquivo não estiver autônomo e estiver em uma linha ou em uma loja, o sistema de arquivos provavelmente não poderá deduzi-lo.
Integridade Muitas pessoas estão aqui falando sobre integridade. O que você acha que é melhor para detectar a corrupção do sistema de arquivos, um aplicativo que usa o sistema de arquivos ou os principais utilitários do sistema de arquivos? Armazene um arquivo em uma linha ou fora de linha e qualquer corrupção no sistema de arquivos será obscurecida no banco de dados.
xfs_repair
é muito bom em se recuperar quando você tem corrupção no sistema de arquivos ou no disco rígido e, se falhar, ainda será muito mais fácil executar a análise forense de dados.Migração na nuvem Se você quiser armazenar os arquivos em uma SAN ou na nuvem, terá mais dificuldade porque agora essa migração de armazenamento é uma migração de banco de dados. Se, por exemplo, seus arquivos estão armazenados no sistema de arquivos, você pode movê-los facilmente para o S3 (e com algo parecido com
s3fs
ele pode ser transparente).Exceções
O armazenamento de arquivos no banco de dados possui alguns casos de uso válidos,
Mitigações
Alguns bancos de dados têm a noção de um "recurso gerenciado externamente", onde o banco de dados gerencia o arquivo de maneira privada no disco, como
O PostgreSQL, por meio da infraestrutura de objetos grandes, fornece um tratamento de arquivos para um recurso durante a transação.
A infraestrutura de fluxo de arquivos do SQL Server 2017 fornece um acesso temporário que dura a duração da transação, que você pode usar para obter o caminho do arquivo e abrir um identificador de arquivo.
A Oracle fornece
BFILE
(isso não tem nada a ver com o material interno de LOB, chamadoSecureFile
Alguns bancos de dados armazenam grandes objetos binários fora de linha ou podem, como o Oracle SecureFile. Isso permite que você atualize a linha, sem reescrever o arquivo.
Alguns bancos de dados como o Oracle fazem seu MVC sem um log WAL e não precisam dobrar a gravação do arquivo.
Alguns bancos de dados, como o SQL Server e o Oracle, oferecem a capacidade de "transmitir" dados do arquivo sem nunca ter um identificador de arquivo. Isso pode ou não ser executado em uma conexão diferente da consulta às bases de dados. Mas a chave aqui é que, embora você possa transmitir o arquivo (em teoria), não consigo encontrar nenhuma evidência de qualquer produto não fabricado pelo provedor que usa esse recurso. Por exemplo, onde está a ponte NGINX / Apache para permitir isso?
O Oracle fornece desduplicação, compactação e criptografia opcionais por meio do armazenamento Internal-LOB (como SecureFile).
Conclusão
O pior cenário possível quando você coloca um arquivo no banco de dados é muito ruim para desempenho e compatibilidade com ferramentas. É sempre excepcionalmente dependente da implementação. De maneira alguma o banco de dados é melhor em ser um sistema de arquivos que o sistema de arquivos. De qualquer forma, é um compromisso e, mesmo quando você obtém recursos poderosos de mitigação (como o caso do SecureFile), as ferramentas são tão precárias que na verdade não são muito mais que um ponto de marketing, a menos que toda a sua pilha seja construída pelo provedor RDBMS.
Mantenha as coisas simples e a regra geral é manter os arquivos fora do banco de dados .
Solução
Como você deve armazenar arquivos ou abstrair um sistema de arquivos dessa maneira para funcionar efetivamente para vários inquilinos e usuários? Eu sou parcial em hash do conteúdo do arquivo. Isso é bastante comum hoje em dia e funciona bem.
fonte
Embora dependa parcialmente do aplicativo / ambiente (pessoas incluídas), eu usaria o blob.
Manter tudo no banco de dados significa que a replicação funciona para os dados do arquivo. Você precisaria de um mecanismo separado para sincronizar arquivos FS.
Em algumas aplicações, o sistema de arquivos não deve ser modificado de qualquer maneira. Por exemplo, em um site de produção, eu evitaria usar o sistema de arquivos para quaisquer dados não descartáveis (o site vive sob um SCM, dados em um banco de dados).
Supondo que tenhamos vários usuários / aplicativos com permissões separadas, qualquer armazenamento do sistema de arquivos oferece uma oportunidade para diferenças nos direitos de acesso ao DB e FS.
O refinamento que eu consideraria fazer no armazenamento BLOB é agrupar os dados, se fizer sentido; se você só precisa de 512 bytes de um BLOB de 20 Mb, esse acesso do setor é um benefício real, especialmente se você estiver lidando com clientes remotos (e, novamente, uma atualização parcial cria muito menos tráfego de replicação).
fonte
Meu voto seria a favor de nenhum dos dois. Armazene os dados em um sistema como o Amazon S3 ou a CDN da Microsft e armazene esse URL no banco de dados.
Dessa forma, você obtém a confiabilidade de ter os dados sempre acessíveis sem ter bancos de dados de tamanho monstro para lidar.
fonte
Para o postgres:
Na verdade, é direto para a frente. Existe um
BYTEA
tipo que pode ser usado para armazenar cadeias binárias. Por padrão, não há utilitários de compilação, como os mencionados para MS ou Oracle. Portanto, armazenar muitos arquivos grandes e recuperá-los pode ser entediante. Você também precisa fazer a conversão dos arquivos dentro do aplicativo (como em umByteStream
ou similar, não faço ideia de como isso funciona com as soluções específicas de banco de dados do arquivo MS / Oracle <->). Há também umlo
tipo que ajuda no trabalho de gerenciamento de BLOBs, já que parte do gerenciamento interno desses tipos pode não acompanhar as referências.fonte
Compartilhe minha experiência no servidor Ms SQL e um grande número de arquivos. Nós salvamos os arquivos em um servidor de arquivos. O banco de dados possui duas tabelas, uma para as pastas de arquivos e credenciais de acesso, uma para o nome do arquivo. É fácil manter o banco de dados e os arquivos. Você pode mover os arquivos facilmente até mesmo entre os servidores, basta modificar a tabela de pastas.
fonte