Atualizando para 2012, quando vemos que os tamanhos e a quantidade de imagens estão crescendo cada vez mais, em todas as aplicações ...
Precisamos de alguma distinção entre "imagem original" e "imagem processada", como a miniatura.
Como diz a resposta de Jcoby, há duas opções, então, eu recomendo:
use blob (Binary Large OBject): para armazenar imagens originais, na sua mesa. Veja a resposta de Ivan (não há problema em fazer backup de blobs!), Módulos adicionais fornecidos pelo PostgreSQL , instruções etc.
use um banco de dados separado com DBlink : para armazenamento de imagem original, em outro banco de dados (unificado / especializado). Nesse caso, prefiro bytea , mas blob é quase o mesmo. Separar o banco de dados é a melhor maneira de um "serviço da web de imagem unificada".
use bytea (BYTE Array): para armazenar imagens em miniatura. Armazene as pequenas imagens em cache para enviá-las rapidamente ao navegador da Web (para evitar problemas de renderização) e reduzir o processamento do servidor. Cache também metadados essenciais, como largura e altura. O armazenamento em cache do banco de dados é a maneira mais fácil, mas verifique suas necessidades e configurações do servidor (ex. Módulos do Apache): armazenar miniaturas no sistema de arquivos pode ser melhor, compare o desempenho. Lembre-se de que é um serviço da Web (unificado), então pode ser armazenado em um banco de dados separado (sem backups), atendendo a várias tabelas. Veja também o manual de tipos de dados binários PostgreSQL , testes com coluna bytea , etc.
NOTA 1: hoje o uso de "soluções duplas" (banco de dados + sistema de arquivos) está obsoleto (!). Há muitas vantagens em usar "somente banco de dados" em vez de dual. PostgreSQL tem desempenho comparável e boas ferramentas para exportação / importação / entrada / saída.
NOTA 2: lembre-se de que o PostgreSQL tem apenas bytea , não tem um BLOB Oracle padrão : "O padrão SQL define (...) BLOB. O formato de entrada é diferente de bytea, mas as funções e operadores fornecidos são basicamente os mesmos", Manual .
EDITAR 2014 : Não mudei o texto original acima hoje (minha resposta foi 22 de abril de 12, agora com 14 votos), estou abrindo a resposta para suas alterações (ver "Modo Wiki", você pode editar!), Para revisão e para atualizações .
A questão está estável (resposta de @Ivans '08 com 19 votos), por favor, ajude a melhorar este texto.
Resposta de Rejoby:
bytea sendo uma coluna "normal" também significa que o valor está sendo lido completamente na memória quando você o busca. Blobs, em contraste, você pode transmitir em stdout. Isso ajuda a reduzir o consumo de memória do servidor. Especialmente, quando você armazena de 4 a 6 imagens MPix.
Não há problema em fazer backup de blobs. O pg_dump fornece a opção "-b" para incluir os objetos grandes no backup.
Então, eu prefiro usar pg_lo_ *, você pode adivinhar.
Resposta de Re Kris Erickson:
Eu diria o contrário :). Quando as imagens não são os únicos dados que você armazena, não as armazene no sistema de arquivos, a menos que seja absolutamente necessário. É um grande benefício estar sempre certo sobre a consistência dos dados e ter os dados "inteiros" (o banco de dados). BTW, PostgreSQL é ótimo em preservar a consistência.
No entanto, é verdade, a realidade costuma exigir muito de desempenho ;-), e força você a servir os arquivos binários do sistema de arquivos. Mas mesmo assim, tendo a usar o banco de dados como o armazenamento "mestre" para binários, com todas as outras relações consistentemente vinculadas, enquanto forneço algum mecanismo de cache baseado em sistema de arquivos para otimização de desempenho.
fonte
BYTEA
ser uma coluna "normal". Postgres tem suportado streaming de / paraBYTEA
colunas por muitos anos, o que significa que você não precisa armazenar o conteúdo na memória antes de armazená-lo no banco de dados.No banco de dados, existem duas opções:
Eu usei colunas bytea com grande sucesso no passado, armazenando mais de 10 gb de imagens com milhares de linhas. A funcionalidade TOAST do PG praticamente nega qualquer vantagem que os blobs tenham. Você precisará incluir colunas de metadados em ambos os casos para nome de arquivo, tipo de conteúdo, dimensões, etc.
fonte
Atualização rápida para meados de 2015:
Você pode usar a interface Postgres Foreign Data , para armazenar os arquivos em um banco de dados mais adequado. Por exemplo, coloque os arquivos em um GridFS que faz parte do MongoDB. Em seguida, use https://github.com/EnterpriseDB/mongo_fdw para acessá-lo no Postgres.
Isso tem as vantagens de poder acessar / ler / gravar / fazer backup no Postrgres e no MongoDB, dependendo do que lhe dá mais flexibilidade.
Também existem wrappers de dados externos para sistemas de arquivos: https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers
Como exemplo, você pode usar este: https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (veja aqui um breve exemplo de uso)
Isso lhe dá a vantagem da consistência (todos os arquivos vinculados estão definitivamente lá) e todos os outros ACIDs, enquanto ainda estão no sistema de arquivos real, o que significa que você pode usar qualquer sistema de arquivos que desejar e o servidor da web pode atendê-los diretamente ( O cache do sistema operacional também se aplica).
fonte
Atualização de 10 anos depois Em 2008, os discos rígidos nos quais você executaria um banco de dados teriam características muito diferentes e um custo muito mais alto do que os discos nos quais você armazenaria os arquivos. Atualmente, existem soluções muito melhores para armazenar arquivos que não existiam há 10 anos e eu revogaria este conselho e aconselharia os leitores a olharem algumas das outras respostas neste tópico.
Original
Não armazene imagens no banco de dados, a menos que seja absolutamente necessário. Eu entendo que este não é um aplicativo da web, mas se não houver um local de arquivo compartilhado que você pode apontar para salvar o local do arquivo no banco de dados.
então, talvez você possa configurar rapidamente um servidor web e armazenar os urls da web no banco de dados (assim como o caminho local). Embora os bancos de dados possam lidar com LOBs e 3.000 imagens (4-6 megapixels, assumindo 500K por imagem) 1.5 Gigs não é muito, os sistemas de arquivos espaciais são muito mais bem projetados para armazenar arquivos grandes do que um banco de dados.
fonte
Experimente isso . Eu usei o formato Large Object Binary (LOB) para armazenar documentos PDF gerados, alguns dos quais tinham mais de 10 MB de tamanho, em um banco de dados e funcionou maravilhosamente bem.
fonte
Se suas imagens forem pequenas, considere armazená-las como base64 em um campo de texto simples.
A razão é que enquanto a base64 tem um overhead de 33%, a compactação praticamente desaparece. (Consulte Qual é a sobrecarga de espaço da codificação Base64? ) Seu banco de dados será maior, mas os pacotes que seu servidor envia ao cliente não. Em html, você pode embutir base64 em uma tag <img src = "">, o que pode simplificar seu aplicativo porque você não terá que servir as imagens como binárias em uma busca de navegador separada. Manusear imagens como texto também simplifica as coisas quando você precisa enviar / receber json, o que não lida muito bem com binários.
Sim, eu entendo que você pode armazenar o binário no banco de dados e convertê-lo de / para texto ao entrar e sair do banco de dados, mas às vezes os ORMs tornam isso um incômodo. Pode ser mais simples apenas tratá-lo como um texto simples, como todos os outros campos.
Esta é definitivamente a maneira certa de lidar com miniaturas.
(As imagens de OP não são pequenas, então esta não é realmente uma resposta à sua pergunta.)
fonte