用ORACLE数据库存储海量图像数据

用ORACLE数据库存储海量图像数据

作者:郑浩 张蔚

在利用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_STORE

DATAFILE'C:/DATABASE/test.dbf' SIZE 200M

 

(2)创建表:

 

create table part(

part_id NUMBER, 主建

part_name VARCHAR2(20),

part_image BLOB,

part_desc CLOB

part_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 OraSession

Dim OraDatabase As OraDatabase

Dim OraDynaset As OraDynaset

Dim PartDesc As OraClob

Dim buffer As String

Dim chunksize As Long

Dim 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").Value

chunksize = 32000

重新调整buffer大小

buffer = String$(chunksize, 32)

FNum = FreeFile

'打开文件

Open "partdesc.dat" For Binary As #FNum

'设置offset和PollingAmount属性

'写入操作

PartDesc.offset = 1

PartDesc.PollingAmount = LOF(FNum)

remainder = LOF(FNum)

'锁定写入行

OraDynaset.Edit

Get #FNum, , buffer

'第一次写入操作

amount_written = PartDesc.Write(buffer, chunksize, ORALOB_FIRST_PIECE)

While PartDesc.Status = ORALOB_NEED_DATA

remainder = remainder - chunksize

If remainder < chunksize Then

piecetype = ORALOB_LAST_PIECE

chunksize = remainder

Else

piecetype = ORALOB_NEXT_PIECE

End If

Get #FNum, , buffer

amount_written = PartDesc.Write(buffer, chunksize, piecetype)

Wend

Close FNum

'更新提交

OraDynaset.Update

 

从数据库中读取数据:

 

Dim OraSession As OraSession

Dim OraDatabase As OraDatabase

Dim OraDynaset As OraDynaset

Dim PartImage As OraBlob

Dim chunksize As Long

Dim AmountRead As Long

Dim buffer As Variant

Dim 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 = 1

PartImage.PollingAmount = PartImage.Size

chunksize = 50000

'获得自由文件号

FNum = FreeFile

'打开文件

Open "image.dat" For Binary As #FNum

'第一次读

AmountRead = PartImage.Read(buffer, chunksize)

buf = buffer

Put #FNum, , buf

' 检查属性

While PartImage.Status = ORALOB_NEED_DATA

AmountRead = PartImage.Read(buffer, chunksize)

buf = buffer

Put #FNum, , buf

Wend

Close FNum

 

五、分析与展望

 

随着数据库管理系统功能的不断增强、性能的不断完善,将各类数据完全由数据库管理系统统一存储和管理,已成为技术发展的趋势。只有这样,数据库管理系统的强大功能才能得到充分发挥,数据的安全性才能得到充分的保障,使得诸如数据库复制、数据的转移等许多工作,变得非常简单容易。

 

但是,也应当清醒的认识到对于大数据量的图像数据的存储,我们还有许多问题要进行研究。一个问题就是大对象数据的特殊操作实现,因为lob型数据是二进制的大对象,他不能简单的按照一般数据的操作符来进行计算。比如,要查出一个数据表中含有大对象的图像,如果图像很大,我们又要进行浏览,那怎么办呢?如果直接进行读取那速度是难以忍受的。只有采取分块或添加索引影像的方法,由此会带来许多需要研究的问题。

 

另外一个重要的问题就是对海量图像数据库的性能优化,原先的优化方法如索引优化等仍然适用,但是现在遇到了新的问题:海量图像数据是庞大的,那么对海量图像数据的操作(尤其是检索)开销巨大,那么如何降低这种开销,缩短操作时间,又是一个重要课题。

 

(来源:CCW)  

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页