none
Imagem no Banco de Dados

    Question

  • Turma,

    Estou com uma dúvida tremanda.

    Temos cerca de 20mil imagens, sendo que cada uma com cerca de 300kb para serem utilizadas pelo nosso sistema.

    Estou achando que colocar essas imagens no banco de dados fica muito complicado e o banco pode ficar enorme.

    Tenho a seguinte idéia:

    Criar uma pasta no servidor (não compartilhada) que guardaria todas as imagens lá. Talvez o nome do arquivo seja o id a qual ela se refere.

    Criar um método dentro do sistema que faça o upload da imagem para essa pasta.

    E na procedure de seleção seria retornada mais uma coluna que seria a imagem e não o caminho dela. Neste momento é que eu tenho dúvida. Como retornar um arquivo que está no hd como uma coluna na sp?

    Ex:
    Select col1,col2, cast(\\servidor\pasta as varbinary) form tabela


    Enfim, como fazer com que eu consiga retornar uma coluna dentro de uma instrução select que seja a imagem?

    Aguardo sugestões para resolver esse problema.

    Valeu !!!
    Thursday, May 08, 2008 2:48 PM

Answers

  • Olá Pablício,

     

    Antes de detalhar uma solução vamos conversar um pouco sobre arquitetura. Você pode colocar as imagens em um banco de dados ou em um servidor de arquivos e realmente temos vantagens e desvantagens (sendo que algumas dessas são contornáveis)

     

    Banco de dados

    - O backup é íntegro (não há como as imagens ficarem dessincronizadas dos dados)

    - A segurança é definida em um único local e é mais eficiente que permissões em nível de arquivo

    - As imagens podem fragmentar os dados mais rapidamente

    - O tamanho do banco irá crescer mais rapidamente

     

    Servidor de Arquivos

    - Ler uma imagem não requer o overhead de conexões a banco de dados e estabelecer um contexto de segurança

    - Você pode trabalhar uma imagem individual (alguém copiá-la por exemplo) sem requerer acesso ao banco de dados

    - O espaço é mais administrável (é possível adicionar novos HDs, mover pastas, etc mais facilmente)

     

    Antigamente eu defendia árduamente que uma imagem não deveria ficar em um banco de dados. Hoje já penso que o banco de dados pode (não necessariamente deve) ser uma boa alternativa. É possível contornar as limitações através da utilização de FILEGROUPs por exemplo.

     

    No entanto, a sua alternativa não seria muito interessante. Ter as imagens no servidor de arquivos e querer recuperar os binários dessas imagens através de uma SP é possível mas muito despendioso. Seria necessário que a SP carregasse as imagens para o banco e as recuperasse. Seria melhor simplesmente recuperar o local das imagens e em sua aplicação recuperar a imagem.

     

    A título de informação, o SQL Server 2008 possui um tipo de dados FILESYSTEM que promete resolver esses impasses.

     

    [ ]s,

     

    Gustavo

    Thursday, May 08, 2008 3:01 PM

All replies

  • Olá Pablício,

     

    Antes de detalhar uma solução vamos conversar um pouco sobre arquitetura. Você pode colocar as imagens em um banco de dados ou em um servidor de arquivos e realmente temos vantagens e desvantagens (sendo que algumas dessas são contornáveis)

     

    Banco de dados

    - O backup é íntegro (não há como as imagens ficarem dessincronizadas dos dados)

    - A segurança é definida em um único local e é mais eficiente que permissões em nível de arquivo

    - As imagens podem fragmentar os dados mais rapidamente

    - O tamanho do banco irá crescer mais rapidamente

     

    Servidor de Arquivos

    - Ler uma imagem não requer o overhead de conexões a banco de dados e estabelecer um contexto de segurança

    - Você pode trabalhar uma imagem individual (alguém copiá-la por exemplo) sem requerer acesso ao banco de dados

    - O espaço é mais administrável (é possível adicionar novos HDs, mover pastas, etc mais facilmente)

     

    Antigamente eu defendia árduamente que uma imagem não deveria ficar em um banco de dados. Hoje já penso que o banco de dados pode (não necessariamente deve) ser uma boa alternativa. É possível contornar as limitações através da utilização de FILEGROUPs por exemplo.

     

    No entanto, a sua alternativa não seria muito interessante. Ter as imagens no servidor de arquivos e querer recuperar os binários dessas imagens através de uma SP é possível mas muito despendioso. Seria necessário que a SP carregasse as imagens para o banco e as recuperasse. Seria melhor simplesmente recuperar o local das imagens e em sua aplicação recuperar a imagem.

     

    A título de informação, o SQL Server 2008 possui um tipo de dados FILESYSTEM que promete resolver esses impasses.

     

    [ ]s,

     

    Gustavo

    Thursday, May 08, 2008 3:01 PM
  • Gustavo, mais uma vez obrigado pelas explicações e pela explanação sobre o assunto.
    Concordo contigo sobre as vantagens e desvantagens.
    Quanto a sugestão de Filegroups terei que pesquisar como funciona dentro do MSDE e do SQLExpress pois essas são as versões que utilizamos do banco de dados. Caso tenha alguma sugestão ou orientação agradeço desde já. Mas o mais importante no meu caso e que eu não ultrapasse nenhuma limitação das versões de bancos que utilizados.
    Valeu !!!
    Thursday, May 08, 2008 3:24 PM
  • Olá Pablício,

     

    Com você precisa manter um "denominador comum" entre o MSDE e o SQL Server Express, teremos no máximo 2GB como tamanho de banco de dados. Nesse caso o tamanho seria uma forte restrição e talvez colocar as imagens no banco de dados não seja uma boa idéia.

     

    Se sua aplicação for WEB, você pode armazenar no banco de dados o link para o arquivo e carregá-lo durante a montagem da página. Se sua aplicação for Destktop você pode fazer um processo semelhante.

     

    No caso do SQL Server Express, é possível usar uma SP para recuperar os dados e o binário da imagem. No entanto isso iria onerar demasiadamente o desempenho. No caso do MSDE essa alternativa seria igualmente penosa e de muito difícil implementação.

     

    Acredito que para o seu cenário o mais adequado mesmo seja carregar os arquivos a partir da aplicação.

     

    [ ]s,

     

    Gustavo

     

    Thursday, May 08, 2008 5:15 PM
  • Gustavo,

    Tem como fazer a leitura da imagem e devolver como uma coluna no retorno de uma sp?

    Você mesmo apontou ser lento e penosa, mas mesmo assim queria aprender e conhecer esse recurso, se é que tem.

    Valeu !!!
    Thursday, May 08, 2008 6:13 PM
  • Olá Pablício,

     

    Sim. Isso é possível. Mas fazer dessa forma não é um pouco lento, é muito lento...

     

    SQL Server 2005

    Você tem de fazer um BULK da imagem junto com o seu SELECT. Ex:

     

    Code Snippet

    WITH Imagens (Arquivo, Conteudo)

    AS (

    SELECT 'bigfoot.bmp', * FROM OPENROWSET(BULK N'C:\bigfoot.bmp', SINGLE_BLOB) As Conteudo)

     

    SELECT * FROM Tabela

    JOIN Imagens ON Tabela.Arquivo = Imagens.Arquivo

     

     

    Volto a ressaltar que isso não possui nenhuma vantagem em relação a qualquer implementação. Fazer com o que o banco de dados carregue uma imagem para que depois repasse a imagem para uma aplicação é colocar um "componente" intermediário que não oferece nenhum benefício

     

    SQL Server 2000

    Você teria que rodar a XP_CMDSHELL com o utilitário textcopy para carregar a imagem e posteriormente exibí-la. Se a implementação acima só possui desvantagens além de um desempenho ruim, a do SQL Server 2000 eu nem me atrevo a postá-la.

     

    Acho interessante a curiosidade para aprendizado, mas confesso que não me agrada muito postar código não recomendável. Espero que sua dúvida tenha sido resolvida.

     

    [ ]s,

     

    Gustavo

    Thursday, May 08, 2008 6:38 PM
  • Gustavo,

    Muito obrigado pela ajuda. E fique tranquilo, pois a idéia é somente para aprendizado e mais ainda, para aprender o que não deve fazer.

    Valeu !!!

    Thursday, May 08, 2008 7:25 PM