用ORACLE數據庫存儲海量圖像數據
2024-08-29 13:33:50
供稿:網友
 
                 在利用Oracle平臺進行數據庫系統的開發過程中,對于海量圖像數據的治理,目前,大都采用表+實體的方法,即圖像數據以文件形式存放于指定的計算機目錄下,在數據庫表中只反映圖像數據文件的存儲路徑。                                                                                            這種治理模式,給數據的維護增加了難度,同時,也給數據的安全帶來一定的隱患。因此,要真正做到各類數據在數據庫中安全治理,研究和探索直接將海量圖像數據存儲在數據庫關系表中的方法是非常必要的。數據庫 
  筆者在Visual Basic 6.0開發環境中,采用客戶機/服務器的工作方式,針對ORACLE數據庫關系表中存儲大量圖像數據的問題和存儲海量圖像數據的策略與方法進行了初步探討,提出了一套基本解決方案,供讀者參考。 
  一、大對象數據類型介紹 
  在關系型數據庫中,大數據量圖像數據等大型對象是由lob型字段來進行存取的。在Oracle8i中,正式引入了此標準,以適應多媒體大對象處理的需求。Oracle數據庫中,lob型數據有以下幾種: 
Lob類型 說明 
Clob: 和Oracle7的long型相似,clob可以存儲單字節型數據 
Nclob: Nclob存儲定寬的多字節國家字符集數據 
Blob: 和Oracle7中的long raw類型相似。可以存儲無結構的二進制數據。Oracle8沒有對這種數據進行解釋 ,只是按照原來的形式存儲和檢索它。 
Bfile: Bfile答應對Oracle數據庫以外存儲的大型二進制文件進行只讀形式的訪問。和其它三種lob類型數據 不同的是,bfile類型數據存儲在一個單獨的文件中,該文件不由Oracle來維護。 
特點: 
1.在Oracle7中,相應的long或long raw字段有2g的限制,而lob的限制是4g 。
2.lob可以使用調用接口OCI或者由pl/sql利用dbms_lob包進行操縱。 
3.lob不象long型那樣每個表中最多只有一個字段的限制,其可以有多個,而又可以利用觸發器的特性。
4.lob數據處理可以獲得與其它數據同樣的事物特性。 
5.lob的存儲比較非凡,它并不是跟其他數據存儲在同一個數據庫表中,而是可以單獨存放于不同的表空間中,由一個定位符指向實際的lob數據。     二、存儲海量圖像數據的策略
    圖像數據庫技術一直致力于解決海量數字圖像的有效存儲和治理問題。                                                                                            它是數據庫技術的繼續和發展,一方面,圖像數據和文本數據存在著本質的區別,在文本數據領域得以成功應用的傳統數據庫技術,假如一成不變的照搬到圖像數據庫領域,結果往往是低效,甚至無效;另一方面,傳統數據庫的許多成果,如SQL語言、索引技術等都值得圖像數據庫借鑒。上述兩個方面的結合成為目前圖像數據庫技術發展的主流。    BLOB大對象數據是數據量很大的數據類型,它會占用大量的硬盤空間、內存和網絡資源,因此合理地設計包含有BLOB大對象數據類型的屬性表,對提高存儲效率、查詢速度有很大的影響。一般BLOB大對象的設計原則如下:(1) 盡量不使用BLOB大對象
    二進制大對象并不一定要存儲為text、ntext或者image數據類型,它們也可以作為varchar或者varbinary數據類型村處在表格中。數據類型的選擇要根據將要存儲的BLOB的實際大小。假如數據不會超過8K,那么就使用Varchar或者varbinary數據類型。假如這些大對象的尺寸超過8K,那么就使用text、ntext或者image數據類型。
(2)何時使用BLOB數據類型
在下列情況下,我們可能要使用到BLOB數據類型
·您要將OLE對象(如圖形、聲音等)存入您的數據庫中;
·您要將大型的二進制對象存入您的數據庫中;
·您所要操縱的文本對象過大,以致于一般的字符串函數無法對其操作;
·您所使用數據庫的數據類型oracle不能支持,所以您只能使用blob函數對其進行操縱。
(3) 最好將BLOB存儲在數據庫中
   常見的設計問題是將圖片存在數據庫中還是存在文件系統中。在大多數情況下,最好把圖片文件與其它數據一起存在數據庫中。因為將影像數據文件存儲在數據庫中有許多優點:⑴易于治理。當BLOB與其他數據一起存儲在數據庫中時,BLOB和表格是數據一起備份和恢復。這樣就降低了表格數據與BLOB數據不同步的機會,而且降低了其他用戶無意中刪除了文件系統中BLOB數據位置的路徑和風險。另外,將數據存儲在數據庫中BLOB和其他數據的插入、更新和刪除都在同一個事務中實現。這樣就確保了數據的一致性和文件與數據庫之間的一致性。還有一點好處是不需要為文件系統中的文件單獨設置安全性。⑵可伸縮性。盡管文件系統被設計為能夠處理大量不同大小的對象,但是文件系統不能對大量小文件進行優化。在這種情況下,數據庫系統可以進行優化。
                         ⑶可用性。數據庫具有比文件系統更多的可用性。數據庫復制答應在分布式環境中復制、分配和潛在的修改數據。在主系統失效的情況下,日志轉移提供了保留數據庫備用副本的方法。當然,在某些情況下,將圖片存儲在文件系統中將是更好的選擇:(1)使用圖片的應用程序需要數據流性能,例如實時的視頻重現。
(2)象Microsoft PhotoDraw或者Adobe photoshop這樣的應用程序經常訪問BLOB,這些應用程序只知道怎樣訪問文件。
(3)需要使用一些NTFS文件系統中的非凡功能,例如遠程存儲。    三、海量數據存儲、備份及分發
(1)存儲
                                                                                                目前對數據的存儲可分為兩大類型,一種是傳統的以主機為中心的存儲方式,另一種是基于網絡的以網絡為中心的存儲方式。與傳統的存儲方式相比,網絡存儲具有更大的靈活性,可以實現對所有數據的共享,可以較好地保持數據的一致性、完整性和安全性。存儲方式有許多,最常用的是磁帶庫和磁盤陣列。但是,磁盤陣列價格昂貴,磁帶庫又有很多缺點。最近,市面上出現了一種叫光盤庫的東西。DVD光盤庫,非凡是DVD-RAM光盤庫適用于所有大容量資料數據的存儲場合,適合存儲一些資料性的不經常更改的數據,比如:醫院的醫療影像資料、銀行等金融機構的重要票據影像資料、圖書館的書庫、電視臺的音像資料庫等等。
   DVD光盤庫不僅支持傳統的文件,而且可以支持各種類型的數據庫,例如Oracle、Informix、SQL等,用戶可以直接把數據庫的表空間建立在光盤庫中的DVD-RAM光盤上,可以支持數據查詢和數據插入、修改、刪除等操作,對于用戶完全透明,感覺就如同使用硬盤一樣方便。但是,目前DVD光盤庫的技術似乎不太成熟,還不能作為安全性較高的數據庫的存儲設備。(2)備份
    光盤作為一種近十年才興起的存儲介質,同傳統的磁帶、軟磁盤相比具有不可同日而語的優點。CD/DVD光盤由于容量大,目前單盤9.4GB,日后容量將迅速突破20GB、易保存,保存期長達30年以上,可靠性高,即使表面磨損,也可用幾百元一臺的修復機迅速修復,攜帶方便,數據交換方便,每臺PC目前大部分都安裝了光盤驅動器。非凡DVD-RAM作為一種世界潮流的新存儲介質將擁有無可限量的前途。既可以用作普通的備份介質又可用作實時的存儲載體。    磁帶非凡是數據流磁帶的單盤容量確實較大,可達到500GB,但這樣一盤磁帶的價格將近1000美元,同時磁帶如保管不善易發霉、易磨損,接近磁體時易數據丟失,而且不同格式的磁帶驅動器也不相兼容,造成了介質數據交換不便。光盤與硬盤相比也有許多無可比擬的優點,硬盤本身比較脆弱,碰到大的震動、沖擊,輕易損壞,光盤就可很好的解決這些問題。所以,大型圖像數據庫系統所有數據的備份能通過光盤完成是最好的選擇。(3)分發
    目前,DVD驅動器已經成為IT行業的一種標準輸入輸出設備,單張DVD光盤片容量大,如DVD-ROM(4.7GB)、DVD-RAM(9.4GB),非常適合作為分發存儲介質。  
  四、存儲圖像數據的方法舉例 
 4.1 建立具有BLOB字段的ORACLE數據庫 
  按照如下步驟來完成各個操作: 
(1)創建表空間: 
                                                                                            
CREATE TABALEESPACE VIDO_STOREDATAFILE'C:DATABASEtest.dbf' SIZE 200M (2)創建表: 
create table part(part_id NUMBER, 主建part_name VARCHAR2(20),part_image BLOB,part_desc CLOBpart_colla BFILE); 這個數據庫第一列存儲一個碼,第二列存儲名稱,另外三列存儲lob型數據。 
  (3)創建新的用戶:如user1/pass1,賦予connect,resource權限。 
  (4)創建邏輯目錄: 
    bfile類型有著非凡性,跟clob,blob不同。實際的數據文件存儲在的外面:所以有兩個特點:1.沒有事務性控制 2.bfile是只讀的,不能用dbms_lob或oracl8 oci進行修改。 為了訪問外部文件,服務器需要知道文件在操作系統中的位置。下面我們建立一個目錄:操作系統 
  create DirectorY utils AS '/home/utils'; 
 utils表示目錄邏輯名,'/home/utils'是實際目錄。 
總結: 
表空間 VIDO_STORE 
Oracle service_names: oradb 
Oracle用戶名: user1
戶名密碼: pass1 
測試表名: test 
tnsnames: oradb 
邏輯目錄: utils 
4.2利用Visual Basic 6.0來處理大對象 
    在vb中處理大對象,一般可以用OO4O(oracle objects for ole)來處理。這里介紹一種不用0040處理大對象blob的方法。 
下面這段程序可以將一個圖像數據保存到數據庫中,并可以將其從數據庫讀出。 
程序中需要兩個commandbutton 
cmd1 名稱 cmdsave caption 保存 
cmd2 名稱 cmdread caption 讀取 
向數據庫中寫入數據: Dim Orasession As OraSessionDim OraDatabase As OraDatabaseDim OraDynaset As OraDynasetDim PartDesc As OraClobDim buffer As StringDim chunksize As LongDim amount_written As Long'建立OraSession對象. Set OraSession = CreateObject("OracleInPRocServer.XOraSession")'打開數據庫連接建立OraDatabase 對象. Set OraDatabase = OraSession.OpenDatabase("ExampleDb", "scott/tiger", 0&)'建立 OraDynaset 對象 Set OraDynaset = OraDatabase.CreateDynaset("select * from part", 0&)Set PartDesc = OraDynaset.Fields("part_desc").Valuechunksize = 32000  
                         
重新調整buffer大小 
buffer = String$(chunksize, 32)FNum = FreeFile'打開文件 Open "partdesc.dat" For Binary As #FNum'設置offset和PollingAmount屬性 '寫入操作 PartDesc.offset = 1PartDesc.PollingAmount = LOF(FNum)remainder = LOF(FNum)'鎖定寫入行 OraDynaset.EditGet #FNum, , buffer'第一次寫入操作 amount_written = PartDesc.Write(buffer, chunksize, ORALOB_FIRST_PIECE)While PartDesc.Status = ORALOB_NEED_DATAremainder = remainder - chunksizeIf remainder < chunksize Thenpiecetype = ORALOB_LAST_PIECEchunksize = remainderElsepiecetype = ORALOB_NEXT_PIECEEnd IfGet #FNum, , bufferamount_written = PartDesc.Write(buffer, chunksize, piecetype)WendClose FNum'更新提交 OraDynaset.Update從數據庫中讀取數據:Dim OraSession As OraSessionDim OraDatabase As OraDatabaseDim OraDynaset As OraDynasetDim PartImage As OraBlobDim chunksize As LongDim AmountRead As LongDim buffer As VariantDim buf() As Byte'建立 OraSession對象 Set OraSession = CreateObject("OracleInProcServer.XOraSession")'建立OraDatabase對象 Set OraDatabase = OraSession.OpenDatabase("ExampleDb","scott/tiger", 0&)'建立OraDynaset對象 Set OraDynaset = OraDatabase.CreateDynaset("select * from part", 0&)'從動態集中獲得OraBlob Set PartImage = OraDynaset.Fields("part_image").Value'設置Offset和PollingAmount屬性 PartImage.offset = 1PartImage.PollingAmount = PartImage.Sizechunksize = 50000'獲得自由文件號 FNum = FreeFile'打開文件 Open "image.dat" For Binary As #FNum'第一次讀 AmountRead = PartImage.Read(buffer, chunksize)buf = bufferPut #FNum, , buf' 檢查屬性 While PartImage.Status = ORALOB_NEED_DATAAmountRead = PartImage.Read(buffer, chunksize)buf = bufferPut #FNum, , bufWendClose FNum    五、分析與展望 
  隨著數據庫治理系統功能的不斷增強、性能的不斷完善,將各類數據完全由數據庫治理系統統一存儲和治理,已成為技術發展的趨勢。                                                                                            只有這樣,數據庫治理系統的強大功能才能得到充分發揮,數據的安全性才能得到充分的保障,使得諸如數據庫復制、數據的轉移等許多工作,變得非常簡單輕易。 
   可是,也應當清醒的熟悉到對于大數據量的圖像數據的存儲,我們還有許多問題要進行研究。一個問題就是大對象數據的非凡操作實現,因為lob型數據是二進制的大對象,他不能簡單的按照一般數據的操作符來進行計算。比如,要查出一個數據表中含有大對象的圖像,假如圖像很大,我們又要進行瀏覽,那怎么辦呢?假如直接進行讀取那速度是難以忍受的。只有采取分塊或添加索引影像的方法,由此會帶來許多需要研究的問題。 
  
  另外一個重要的問題就是對海量圖像數據庫的性能優化,原先的優化方法如索引優化等仍然適用,但是現在碰到了新的問題:海量圖像數據是龐大的,那么對海量圖像數據的操作(尤其是檢索)開銷巨大,那么如何降低這種開銷,縮短操作時間,又是一個重要課題。