PostgreSQL에 이미지 저장


111

좋습니다. 저는 PostgreSQL을 실행하는 Linux 백엔드를 사용하여 C # .NET으로 작성된 프런트 엔드가있는 Windows 상자에 이미지를 제공하는 응용 프로그램을 작업 중이지만 프런트 엔드는 거의 중요하지 않습니다. 내 질문은 :

  • Postgres에 이미지를 저장하는 가장 좋은 방법은 무엇입니까?

이미지는 각각 약 4 ~ 6 메가 픽셀이며 3000 개 이상을 저장하고 있습니다. 이것은 웹 애플리케이션이 아니며 한 번에 데이터베이스에 액세스하는 프런트 엔드가 최대 2 개입니다.

답변:


64

2012 년으로 업데이트하면 모든 애플리케이션에서 이미지 크기와 이미지 수가 증가하고 증가하는 것을 볼 수 있습니다.

미리보기 이미지와 같이 '원본 이미지'와 '처리 된 이미지'를 구분해야합니다.

Jcoby의 답변에 따르면 두 가지 옵션이 있으므로 다음을 권장합니다.

  • blob (Binary Large OBject) 사용 : 테이블에서 원본 이미지 저장 소용 . Ivan의 답변 (블롭 백업에 문제 없음!), PostgreSQL 추가 제공 모듈 , 방법 등을 참조하십시오.

  • DBlink 와 함께 별도의 데이터베이스를 사용 하십시오 . 원본 이미지 저장소의 경우 다른 (통합 / 특수) 데이터베이스에 있습니다. 이 경우에는 bytea를 선호 하지만 blob 은 거의 동일합니다. 데이터베이스 분리는 "통합 이미지 웹 서비스"를위한 가장 좋은 방법입니다.

  • use bytea (BYTE Array) : 썸네일 이미지 캐싱 용. 작은 이미지를 캐시하여 웹 브라우저로 빠르게 보내고 (렌더링 문제를 방지하기 위해) 서버 처리를 줄입니다. 너비 및 높이와 같은 필수 메타 데이터도 캐시합니다. 데이터베이스 캐싱이 가장 쉬운 방법이지만 필요와 서버 구성 (예 : Apache 모듈)을 확인하십시오. 파일 시스템에 썸네일을 저장하는 것이 더 좋을 수 있으며 성능을 비교합니다. 이는 (통합) 웹 서비스이므로 별도의 데이터베이스 (백업 없음)에 저장하여 많은 테이블을 제공 할 수 있습니다. PostgreSQL 바이너리 데이터 유형 매뉴얼 , bytea 열을 사용한 테스트 등을 참조하십시오 .

NOTE1 : 오늘날 "이중 솔루션"(데이터베이스 + 파일 시스템) 은 더 이상 사용되지 않습니다 (!). 이중 대신 "데이터베이스 만"을 사용하면 많은 이점이 있습니다. PostgreSQL은 내보내기 / 가져 오기 / 입력 / 출력을위한 비슷한 성능과 훌륭한 도구를 제공합니다.

NOTE2 : PostgreSQL에는 기본 Oracle의 BLOB 가없고 bytea 만 있다는 것을 기억하십시오 . "SQL 표준은 BLOB를 정의합니다. 입력 형식은 bytea와 다르지만 제공된 함수와 연산자는 거의 동일합니다.", Manual .


편집 2014 : 나는 (내 대답은 14 표에 지금 4 월 (22) '12이었다)는 오늘 위의 원본 텍스트를 변경하지 않은 내가 변경 사항에 대한 답을 개방하고 (편집 할 수있는 "위키 모드"를 참조하십시오!)에 대한 교정업데이트 .
질문은 안정적입니다 (@Ivans의 '08 답변 19 표).이 텍스트를 개선하는 데 도움을주세요.


2
"..."이중 솔루션 "(데이터베이스 + 파일 시스템) 사용이 더 이상 사용되지 않음 ..."에 대한 참조는 무엇입니까?
dangel

2019 년 소식! 2018 년부터 PostgREST는 웹 에 bytea의 직접 출력을 지원합니다 . 이 NGINX 간단한 구성 을 참조하십시오 . 바이너리 출력에 대한 PostgREST 가이드
Peter Krauss

52

Re jcoby의 답변 :

bytea가 "정상"열이라는 것은 또한 값을 가져올 때 메모리로 완전히 읽혀지는 값을 의미합니다. 반대로 Blob은 stdout으로 스트리밍 할 수 있습니다. 이는 서버 메모리 공간을 줄이는 데 도움이됩니다. 특히 4-6 MPix 이미지를 저장할 때.

Blob 백업에 문제가 없습니다. pg_dump는 큰 개체를 백업에 포함하는 "-b"옵션을 제공합니다.

그래서 저는 pg_lo_ * 사용을 선호합니다.

Re Kris Erickson의 답변 :

나는 그 반대라고 말하고 싶다 :). 이미지 만 저장하는 데이터가 아닌 경우 꼭 필요한 경우가 아니면 파일 시스템에 저장하지 마십시오. 데이터 일관성을 항상 확인하고 데이터를 "일체형"(DB)으로 유지하는 것은 이러한 이점입니다. BTW, PostgreSQL은 일관성 유지에 탁월합니다.

그러나 사실, 현실은 종종 성능을 너무 많이 요구하고 ;-) 파일 시스템에서 바이너리 파일을 제공하도록 강요합니다. 그러나 그 후에도 DB를 바이너리 용 "마스터"스토리지로 사용하는 경향이 있으며 다른 모든 관계는 일관되게 연결되어 있으며 성능 최적화를위한 파일 시스템 기반 캐싱 메커니즘을 제공합니다.


14
10 년 후에도 포인트가 여전히 유효하다고 생각하십니까? 그 이후로 업데이트가 있습니까?
leventunver

3
@leventunver 아니요, 보유하지 않는 포인트. 예를 들어 BYTEA"정상"열이되는 것에 대한 첫 번째 . Postgres는 수년 동안 열과의 스트리밍 을 지원했습니다. BYTEA즉, 콘텐츠를 db에 저장하기 전에 메모리에 저장할 필요가 없습니다.
oligofren

29

데이터베이스에는 두 가지 옵션이 있습니다.

  • bytea. 백업의 일부로 내 보낸 데이터를 열에 저장합니다. 표준 데이터베이스 기능을 사용하여 저장 및 검색합니다. 귀하의 요구에 권장됩니다.
  • 얼룩. 일반적으로 백업의 일부로 내 보내지 않고 데이터를 외부에 저장합니다. 저장 및 검색하려면 특수 데이터베이스 기능이 필요합니다.

나는 과거에 수천 개의 행으로 10GB 이상의 이미지를 저장하는 데 큰 성공을 거둔 bytea 열을 사용했습니다. PG의 TOAST 기능은 Blob이 갖는 모든 이점을 거의 무효화합니다. 파일 이름, 콘텐츠 유형, 크기 등에 대한 메타 데이터 열을 두 경우 모두 포함해야합니다.


1
10GB는 그리 많지 않습니다 :-( TB 솔루션을 찾고 있습니다
Valentin Heinitz 2017 년

2
@ValentinHeinitz TB의 경우 vanilla Postgres는 작은 텍스트 열로도 어려움을 겪습니다.
sudo

23

2015 년 중반까지의 빠른 업데이트 :

당신은 사용할 수 있습니다 포스트 그레스 외부 데이터 인터페이스를 더 적합 데이터베이스에 파일을 저장합니다. 예를 들어 MongoDB의 일부인 GridFS에 파일을 넣습니다. 그런 다음 https://github.com/EnterpriseDB/mongo_fdw 를 사용 하여 Postgres에서 액세스합니다.

그것은 당신에게 더 많은 유연성을 제공하는 것에 따라 Postrgres 및 MongoDB에서 액세스 / 읽기 / 쓰기 / 백업 할 수 있다는 장점이 있습니다.

파일 시스템에 대한 외부 데이터 래퍼도 있습니다 : https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers

예를 들어 https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (간단한 사용 예는 여기 참조)을 사용할 수 있습니다.

이는 일관성 (링크 된 모든 파일이 확실히 거기에 있음)과 다른 모든 ACID의 이점을 제공하지만 실제 파일 시스템에 여전히 존재합니다. 즉, 원하는 파일 시스템을 사용할 수 있고 웹 서버가 직접 제공 할 수 있습니다 ( OS 캐싱도 적용됩니다).


1
감사합니다 .. 외부 데이터 래퍼 (file_fdw)가 이미지에 대한 쓰기 액세스를 제공합니까? 이미지를 파일 시스템에 저장하고 해당 메타 데이터를 Postgresql에 저장하고 싶지만 일관성도 유지해야합니다. 자세한 솔루션이 있습니까? 사용 가능한 다른 확장이 있습니까? .. Multicorn 파이썬을 필요로하고 파이썬을 사용하지 않고 할 필요 선호
제이 Khatwani에게

1
예, 그들은 쓰기 권한이 있습니다. 양 방향에서 완전히 일관됩니다. 그리고 저는 파이썬없이 이것을 수행하는 동등한 솔루션을 모릅니다.
Kenyakorn Ketsombut

18

10 년 후 업데이트 2008 년에 데이터베이스를 실행하는 하드 드라이브는 파일을 저장하는 디스크보다 훨씬 더 많은 특성과 비용이 듭니다. 요즘에는 10 년 전에 존재하지 않았던 파일을 저장하는 훨씬 더 나은 솔루션이 있으며이 조언을 취소하고 독자들에게이 스레드의 다른 답변을 살펴 보도록 조언합니다.

실물

꼭 필요한 경우가 아니면 데이터베이스에 이미지를 저장하지 마십시오. 나는 이것이 웹 응용 프로그램이 아니라는 것을 알고 있지만 공유 파일 위치가 없으면 데이터베이스에 파일 위치를 저장할 수 있습니다.

//linuxserver/images/imagexxx.jpg

그런 다음 웹 서버를 빠르게 설정하고 웹 URL을 데이터베이스 (및 로컬 경로)에 저장할 수 있습니다. 데이터베이스는 LOB 및 3000 개의 이미지를 처리 ​​할 수 ​​있지만 (이미지 당 500K를 가정하면 4-6 메가 픽셀) 1.5Gig는 공간이 많지 않습니다. 파일 시스템은 데이터베이스보다 대용량 파일을 저장하는 데 훨씬 적합하도록 설계되었습니다.


15
그러나 여러 디렉토리에 파일을 배포하는 방법을 찾아야합니다. 파일 시스템은 단일 디렉토리 에 백만 개의 파일을 저장하는 데 그다지 좋지 않습니다 (실제로 수만 개는 이미 문제입니다)
a_horse_with_no_name 2013

1
원래 질문에 대답하지 않습니다. SQL을 추상화 계층으로 사용하고 ext4 파일 시스템의 파일을 관리하고 싶지 않기 때문에 개인적으로 Postgres에 이미지를 저장하려고합니다.
sudo

나는 갈등이 있습니다. 이것은 질문에 대한 대답이 아니지만 질문에 대한 대답보다 더 나은 대답이기 때문에 그것을 찬성했습니다.
Andrew Carr

6

이것을 시도 하십시오 . 생성 된 PDF 문서를 저장하기 위해 LOB (Large Object Binary) 형식을 사용했는데, 그중 일부는 크기가 10MB 이상인 데이터베이스에 훌륭하게 작동했습니다.


2

이미지가 작 으면 일반 텍스트 필드에 base64로 저장하는 것이 좋습니다.

그 이유는 base64가 33 %의 오버 헤드를 가지지 만 대부분 압축이 사라지기 때문입니다. ( Base64 인코딩의 공간 오버 헤드는 무엇입니까?를 참조하십시오 . ) 데이터베이스는 더 커지지 만 웹 서버가 클라이언트에 보내는 패킷은 그렇지 않습니다. html에서는 <img src = ""> 태그에 base64를 인라인 할 수 있습니다. 이렇게하면 별도의 브라우저 가져 오기에서 이미지를 바이너리로 제공 할 필요가 없기 때문에 앱을 단순화 할 수 있습니다. 이미지를 텍스트로 처리하면 바이너리를 잘 처리하지 못하는 json을 보내거나 받아야 할 때 작업이 단순화됩니다.

예, 바이너리를 데이터베이스에 저장하고 데이터베이스를 들어오고 나가는 도중에 텍스트로 /로부터 변환 할 수 있다는 것을 이해합니다. 그러나 때때로 ORM이이를 번거롭게 만듭니다. 다른 모든 필드와 마찬가지로 직선 텍스트로 처리하는 것이 더 간단 할 수 있습니다.

이것은 썸네일을 처리하는 올바른 방법입니다.

(OP의 이미지는 작지 않으므로 그의 질문에 대한 답이 아닙니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.