[postgresql] PostgreSQL에 이미지 저장

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

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

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



답변

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 표).이 텍스트를 개선하는 데 도움을주세요.


답변

Re jcoby의 답변 :

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

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

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

Re Kris Erickson의 답변 :

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

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


답변

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

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

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


답변

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 캐싱도 적용됩니다).


답변

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

실물

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

//linuxserver/images/imagexxx.jpg

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


답변

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


답변

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

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

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

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

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