2008-09-10 93 views
74

好的,所以我正在研究一個應用程序,該應用程序將使用運行PostgreSQL的Linux後端將圖像提供給以C#.NET編寫的前端的Windows盒子,儘管前端應該不重要。我的問題是:在PostgreSQL中存儲圖像

  • 什麼是最好的方式來處理存儲在Postgres中的圖像?

的圖像是圍繞每個4-6百萬像素,我們正在儲存向上的3000也可能是好注意:這不是一個Web應用程序,將有至多是大約兩個前置式結束一次訪問數據庫。

回答

20

在數據庫中,有兩種選擇:

  • BYTEA。將數據存儲在列中,作爲備份的一部分導出。使用標準數據庫功能來保存和檢索。推薦您的需求。
  • blob。將數據存儲在外部,通常不作爲備份的一部分導出。需要特殊的數據庫功能來保存和檢索。

我已經使用bytea列在過去成功存儲10 + gb圖像數千行的成功。 PG的TOAST功能幾乎否定了blob具有的優點。您需要在文件名,內容類型,尺寸等情況下包含元數據列。

+0

10GB並不多:-(我正在尋找TBs解決方案 – 2017-06-09 20:33:52

+1

@ValentinHeinitz對於TBs,即使使用較小的文本列,vanilla Postgres仍然在掙扎 – sudo 2017-09-06 20:09:33

2

嘗試this。我使用大對象二進制(LOB)格式將生成的PDF文檔(其中一些文檔的大小超過10 MB)存儲在數據庫中,並且它的工作非常出色。

7

除非絕對必須,否則不要將圖像存儲在數據庫中。我知道這不是一個Web應用程序,但是如果沒有可以指向將文件的位置保存在數據庫中的共享文件位置。

//linuxserver/images/imagexxx.jpg 

那麼也許你可以快速建立一個網絡服務器,並將網址存儲在數據庫中(以及本地路徑)。雖然數據庫可以處理LOB和3000圖像(假設500K的圖像爲4-6萬像素),但1.5G的空間並不是很多,文件系統比數據庫更適合存儲大型文件。

+9

但是您必須想出一種方法將文件分佈到多個目錄中。文件系統並不擅長在單個目錄中存儲數百個文件(實際上有一萬個已經是個問題) – 2013-11-03 10:38:45

44

重新jcoby的回答是:

BYTEA是一個「正常」欄也意味着,當你把它拿來被完全讀入內存的值。 Blob,相反,你可以流入標準輸出。這有助於減少服務器內存佔用。特別是,當您存儲4-6個MPix圖像時。

備份blob沒有問題。 pg_dump提供了「-b」選項來將大對象包含到備份中。

所以,我更喜歡使用pg_lo_ *,你可能會猜到。

Re克里斯埃裏克森的回答:

我會說相反的:)。如果圖像不是您存儲的唯一數據,請不要將它們存儲在文件系統上,除非您絕對必須。對於您的數據一致性以及將數據「整合」(數據庫)來說,這是一個好處。順便說一句,PostgreSQL在保持一致性方面非常出色。

然而,真實的現實通常對性能要求過高;-),它會促使您從文件系統提供二進制文件。但即使如此,我仍傾向於將DB用作二進制文件的「主」存儲,其他所有關係始終保持關聯,同時提供一些基於文件系統的緩存機制以實現性能優化。

41

更新到2012年的時候,我們看到的圖像尺寸和圖像的數量,都在不斷擴張,在所有應用中......

我們需要「原始圖像」和「處理後的圖像」之間的一些區別,像縮略圖一樣。

由於Jcoby的回答說,有兩種選擇,那麼,我建議:

  • 使用BLOB(二進制大對象):原創形象店,在你的餐桌。見伊萬的回答,PostgreSQL additional supplied modulesHow-tos

  • 使用單獨的數據庫與DBlink(有備份的斑點沒問題!):原創形象店,在另一個(統一/專業)數據庫。在這種情況下,我preffer bytea,但blob是幾乎相同。分離數據庫是「統一圖像web服務」的最佳途徑。

  • 使用bytea(字節數組):用於緩存縮略圖圖像。緩存小圖像以快速發送到網頁瀏覽器(避免渲染問題)並減少服務器處理。緩存也是必要的元數據,如寬度和高度。數據庫緩存是最簡單的方法,但檢查您的需求和服務器配置(例如Apache模塊):store thumbnails at file system可能會更好,比較性能。請記住它是一個(統一的)Web服務,然後可以存儲在單獨的數據庫(無備份)中,爲多個表提供服務。另請參見PostgreSQL binary data types manualtests with bytea column

注1:(!)今天使用的"dual solutions" (database+filesystem)已經過時了。使用「唯一數據庫」代替雙重數據庫有很多優點。 PostgreSQL具有可比較的性能和用於導出/導入/輸入/輸出的良好工具。

NOTE2:記住PostgreSQL的只有BYTEA,沒有一個默認Oracle的BLOB:「SQL標準定義(...)BLOB的輸入格式爲BYTEA不同,但所提供的功能和運營商大多是相同的「,Manual


編輯:我沒有改變今天上方的原文(我的答案是04月22日'12,現在有14票),我 正在打開的答案更改(見「維基模式「,你可以編輯!),爲proofreading更新
問題是穩定的(@ Ivans '08回答19票),請幫助改進這個文本。

15

快速更新到2015年中期:

可以使用Postgres的對外數據接口,將文件存儲在更加合適的數據庫。例如把這些文件放在一個屬於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,而實際文件系統上仍存在,這意味着您可以使用任何所需的文件系統,並且Web服務器可以直接爲它們提供服務(也可以使用操作系統緩存)。