Estou escrevendo um aplicativo que permite aos usuários fazer upload de imagens no servidor. Espero cerca de 20 imagens por dia todos os JPEG e provavelmente não editados / redimensionados. (Essa é outra questão: como redimensionar as imagens no servidor antes de armazenar. Talvez alguém possa soltar um recurso .NET para isso no comentário). Gostaria de saber agora qual é o melhor lugar para armazenar imagens carregadas.
Armazene as imagens como um arquivo no sistema de arquivos e crie um registro em uma tabela com o caminho exato para essa imagem.
Ou armazene a própria imagem em uma tabela usando um tipo de dados "imagem" ou "dados binários" do servidor de banco de dados.
Vejo vantagens e desvantagens em ambos. Gosto de a) porque posso realocar facilmente os arquivos e apenas preciso alterar a entrada da tabela. Por outro lado, não gosto de armazenar dados corporativos no servidor Web e não quero realmente conectar o servidor Web a qualquer outra fonte de dados que armazene dados corporativos (por motivos de segurança). Gosto de b) porque todas as informações são em um só lugar e facilmente acessível por uma consulta. Por outro lado, o banco de dados ficará muito grande muito em breve. Terceirizar esses dados pode ser mais difícil.
Respostas:
Geralmente armazeno arquivos no sistema de arquivos, pois é para isso que existe, embora haja exceções. Para arquivos, o sistema de arquivos é a solução mais flexível e com melhor desempenho (geralmente).
Existem alguns problemas com o armazenamento de arquivos em um banco de dados - os arquivos geralmente são muito maiores que a linha média - os conjuntos de resultados que contêm muitos arquivos grandes consomem muita memória. Além disso, se você usar um mecanismo de armazenamento que utilize bloqueios de tabela para gravações (ISAM, por exemplo), sua tabela de arquivos poderá ser bloqueada frequentemente, dependendo do tamanho / taxa de arquivos que você está armazenando lá.
Em relação à segurança - geralmente armazeno os arquivos em um diretório que está fora da raiz do documento (não acessível por meio de uma solicitação http) e os sirvo através de um script que verifica primeiro a devida autorização.
fonte
O único benefício para a opção B é ter todos os dados em um sistema, mas é um benefício falso! Você pode argumentar que seu código também é uma forma de dados e, portanto, também pode ser armazenado no banco de dados - como você gostaria?
A menos que você tenha algum caso exclusivo:
Não é necessário usar o sistema de arquivos para manter os arquivos. Em vez disso, você pode usar o armazenamento em nuvem (como o Amazon S3 ) ou a infraestrutura como serviço em cima dele (como o Uploadcare ):
https://uploadcare.com/upload-api-cloud-storage-and-cdn/
Mas armazenar arquivos no banco de dados é uma má idéia.
fonte
O Flickr usa o sistema de arquivos - eles discutem os motivos aqui
fonte
Eu sei que este é um post antigo. Mas muitos visitantes desta página não estão recebendo nada relacionado à pergunta. Especialmente para um novato.
Como fazer upload e armazenar imagens ou arquivos em nosso site:
Para um site estático, talvez não haja problema, pois o armazenamento de arquivos para alguns compartilhamentos de hospedagem ainda é adequado. O problema vem de um site dinâmico quando fica maior. Maiores no banco de dados podem ser manipulados, mas arquivos maiores, como imagens, tornam-se um problema. Existem dois tipos de imagens em um site:
As imagens são do administrador do blog dinâmico. Geralmente, essas imagens são otimizadas antes do upload.
Imagens de usuários no caso de usuários podem fazer upload de imagens como avatar. Ou os usuários podem criar conteúdo do blog e colocar algumas imagens do editor de texto. Esse tipo de imagem é difícil de prever o tamanho. Os usuários podem fazer upload de imagens grandes apenas para conteúdo pequeno, redimensionando o tamanho da visualização, mas não redimensionando o tamanho da imagem.
Ignorando o item no. 1 acima, solução rápida para o item no. 2 pode ser resolvido temporariamente pelas seguintes dicas, se não tivermos a funcionalidade otimizador de imagem em nosso site:
Não permita que os usuários enviem diretamente do editor de texto, redirecionando-os para a galeria de imagens. Nesta página, os usuários devem fazer upload do arquivo com antecedência antes de poderem incorporar o conteúdo. Este método é chamado como um gerenciador de arquivos.
Use uma função de corte de imagem para os usuários fazerem upload de imagens. Isso limitará o tamanho da imagem, mesmo que os usuários enviem arquivos muito grandes. A imagem final é o resultado da imagem cortada. Podemos definir o tamanho no servidor e aceitar apenas, por exemplo, 500 KB ou menos.
Agora, isso é apenas temporário. Para solução final, a pergunta é repetida:
O que podemos fazer então:
Migrar do compartilhamento de hospedagem VPS. Insuficiente? Mais ainda, atualizando para Dedicado.
Crie seu próprio servidor para armazenamento de arquivos. Pesquisando para fazer isso. Isso não é tão difícil quanto você pensa. Algumas pessoas fazem isso pelo site.
A maneira mais fácil é usar o serviço de armazenamento de arquivos CDN.
Ok, 1 e 2 é um pouco caro. Mas no 3 eu acho que é a melhor solução.
Alguns serviços CDN permitem armazenar quantos arquivos da web você desejar.
Pergunta, "como fazer upload de arquivo para CDN do nosso site?"
Não se preocupe, depois de se registrar, geralmente de graça, você receberá orientações sobre como fazer upload de arquivos e obter o link deles de / para o seu site. Você receberá uma API e muito mais. É fácil.
Alguns provedores nos oferecem um serviço gratuito por 14 dias, com armazenamento e largura de banda limitados. Mas tudo bem como ponto de partida. O único problema é porque 'as pessoas nunca tentam'.
Espero que ajude para iniciantes.
fonte
Tivemos clientes insistindo na opção B (armazenamento de banco de dados) algumas vezes em alguns back-end diferentes, e sempre acabamos voltando à opção A (armazenamento do sistema de arquivos).
BLOBs grandes como esse simplesmente não foram tratados o suficiente, mesmo pelo SQL Server 2005, que é o mais recente em que testamos.
Especificamente, vimos inchaço grave e acho que talvez tenha problemas de bloqueio.
Outra observação: se você estiver usando armazenamento baseado em NTFS (servidor Windows, etc), considere encontrar uma maneira de colocar milhares e milhares de arquivos em um diretório. Não sei por que, mas às vezes o sistema de arquivos não lida bem com essa situação. Se alguém souber mais sobre isso, eu adoraria ouvir.
Mas eu sempre tento usar subdiretórios para quebrar um pouco as coisas. A data de criação geralmente funciona bem para isso:
Images / 2008/12/17 / .jpg
... Isso fornece um nível decente de separação e também ajuda um pouco durante a depuração. Os clientes Explorer e FTP podem engasgar um pouco quando há diretórios realmente grandes.
EDIT: Apenas uma observação rápida para 2017, nas versões mais recentes do SQL Server, há novas opções para lidar com muitos BLOBs que devem evitar as desvantagens que discuti.
EDIT: Observação rápida para 2020, o Armazenamento de Blob no AWS / Azure / etc também é uma opção há anos. Isso é ideal para muitos projetos baseados na Web, pois é barato e muitas vezes pode simplificar certos problemas de implantação, dimensionamento para vários servidores, depuração de outros ambientes quando necessário etc.
fonte
ls
, levaria uma eternidade (trava). Ou exclua.Recentemente, criei um aplicativo PHP / MySQL que armazena arquivos PDF / Word em uma tabela MySQL (até 40 MB por arquivo até agora).
Prós:
Contras:
Eu consideraria minha implementação um sucesso, ele cuida dos requisitos de backup e simplifica o layout do projeto. O desempenho é bom para as 20 a 30 pessoas que usam o aplicativo.
fonte
Eu uso imagens carregadas no meu site e definitivamente diria a opção a).
Outra coisa que eu recomendo é mudar imediatamente o nome do arquivo do nome que o usuário deu à foto, para algo mais gerenciável. Por exemplo, algo com a data e a hora para identificar exclusivamente cada imagem.
Também ajuda a remover o nome de arquivo do usuário de caracteres estranhos para evitar complicações futuras.
fonte
Definitivamente redimensione a imagem e verifique seu formato, se puder. Houve casos de arquivos maliciosos sendo carregados e servidos por hosts involuntários - por exemplo, a vulnerabilidade GIFAR permitiu ocultar um applet java malicioso em um arquivo GIF, que seria capaz de ler cookies no contexto atual e enviá-los para outro site para um ataque de script entre sites. O redimensionamento das imagens geralmente evita isso, uma vez que mescla o código incorporado. Embora esse ataque tenha sido corrigido pelos patches da JVM, o fornecimento ingênuo de arquivos binários sem limpá-los abre uma grande variedade de vulnerabilidades.
Lembre-se de que a maioria dos scanners de vírus pode ser executada apenas no sistema de arquivos. Se você armazenar seus binários no banco de dados, não poderá executar um scanner contra eles com muita facilidade.
fonte
Existe uma abordagem híbrida no SQL Server 2008, chamada de tipo de dados de fluxo de arquivos mencionado no RunAs Radio # 74 , que é como o melhor dos dois mundos. A maioria das pessoas não tem a ação de 2008, mas se você tem, essa opção parece bem legal
fonte
Isso é basicamente o que faço.
id
que será armazenada no banco de dados para qualquer linha / documento, juntamente comimage file name
(ou pode ser um nome aleatório como nome da imagem).path
se não existir. Por exemplo, 21/08/2016. Lembre-se desse caminho e armazene no banco de dados para o mesmo documento e linha.id
pasta da imagem para apath
pasta. (A pasta Path pode estar localizada na pasta / var / conteúdo da web.)Quando você precisa acessar qualquer imagem mencionada em um documento, possui o caminho e o ID da pasta que contém imagens. Por exemplo
/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg
Dessa forma, se você precisar excluir todos os arquivos de imagem processados, exclua a pasta e seu conteúdo recursivamente.
fonte
A maioria das implementações é a opção A.
Com a opção B, você abre uma grande lata de whoop4ss ao organizar esses bits do banco de dados em algo que pode ser exibido em um navegador ... Além disso, se o banco de dados estiver inativo, as imagens não estarão disponíveis.
Eu não acho que o espaço seja muito problemático ... Os discos Terabyte custam algumas centenas de dólares agora.
Estamos implementando com a opção A porque não temos tempo ou recursos para executar a opção B.
fonte
Para redimensionamento automático, tente o imagemagick ... é usado para muitos dos principais sistemas de gerenciamento de conteúdo / foto de código aberto ... e acredito que existem algumas extensões .net para ele.
fonte
Usamos A. Eu o colocaria em uma unidade compartilhada (a menos que você não planeje executar mais de um servidor).
Se chegar o momento em que isso não será dimensionado para você, você poderá investigar os mecanismos de cache.
fonte
Absolutamente, opção positiva A. Outros mencionaram que os bancos de dados geralmente não lidam bem com BLOBs, sejam eles projetados para fazê-lo ou não. Os sistemas de arquivos, por outro lado, vivem desse tipo de coisa. Você tem a opção de usar faixas RAID, espalhar imagens por várias unidades, até espalhá-las por servidores geograficamente diferentes.
Outra vantagem é que os backups / replicação do banco de dados seriam monstruosos.
fonte
Opção A.
Depois que a imagem é carregada, você pode verificar o formato e redimensioná-lo antes de salvar. Há várias amostras de código .Net para redimensionar imagens em http://www.codeproject.com . Por exemplo: http://www.codeproject.com/KB/cs/Photo_Resize.aspx
fonte
Por motivos de segurança, também é uma prática recomendada evitar problemas causados pelo Sniffing de conteúdo do IE, que pode permitir que invasores enviem JavaScript dentro de arquivos de imagem, que podem ser executados no contexto do seu site. Portanto, convém transformar as imagens (cortá-las / redimensioná-las) de alguma forma antes de armazená-las para evitar esse tipo de ataque. Esta resposta tem algumas outras idéias.
fonte
Bem, eu tenho um projeto semelhante no qual os usuários enviam arquivos para o servidor. Do meu ponto de vista, a opção a) é a melhor solução devido à sua flexibilidade. O que você deve fazer é armazenar imagens em uma pasta protegida classificada por subdiretórios. O diretório principal deve ser configurado pelo administrador, pois o conteúdo não deve executar scripts (muito importantes) e (ler, escrever) protegidos para não serem acessíveis na solicitação http.
Espero que isso ajude você.
fonte
Se forem arquivos pequenos que não precisarão ser editados, a opção B não será uma má opção. Eu prefiro isso a escrever lógica para armazenar arquivos e lidar com problemas de estrutura de diretórios malucos. Ter muitos arquivos em um diretório é ruim. emkay?
Se os arquivos forem grandes ou exigirem edição constante, especialmente de programas como o office, a opção A é sua melhor aposta.
Na maioria dos casos, é uma questão de preferência, mas se você optar pela opção A, faça com que os diretórios não possuam muitos arquivos. Se você escolher a opção B, faça com que a tabela com os dados de BLOB esteja em seu próprio banco de dados e / ou grupo de arquivos. Isso ajudará na manutenção, especialmente nos backups / restaurações. Seus dados regulares são provavelmente bastante pequenos, enquanto os dados da imagem serão enormes com o tempo.
fonte
Depende de seus requisitos, especialmente volume, usuários e frequência de pesquisa. Porém, para escritórios pequenos ou médios, a melhor opção é usar um aplicativo como o Apple Photos ou o Adobe Lighroom. Eles são especializados para armazenar, catalogar, indexar e organizar esse tipo de recurso. Porém, para grandes organizações, com fortes requisitos de armazenamento e alto número de usuários, é recomendável instanciar uma plataforma de Gerenciamento de Conteúdo com um Gerenciamento de Ativos Digitais, como Nuxeo ou Alfresco; ambas oferecem recursos muito bons; gerenciam grandes volumes de dados com métodos simplificados para recuperá-los. E, muito importante: existe uma opção gratuita (de código aberto) para ambas as plataformas.
fonte