BLOB移植的替换方案

ZDNet软件频道 时间:2002-09-25 作者:BUILDER.COM |  我要评论()
本文关键词:
能够存储大的二进制对象(BLOB)是数据库的一个共同要求。本文中,我将为PHP和PostgreSQL提供一个解决方案。这个方案是基于标准特性的,所以它应该是很容易就能移植到任何语言/数据库中。
能够存储大的二进制对象(BLOB)是数据库的一个共同要求。但是不幸的是,SQL92标准没有为BLOB定义任何合适的数据类型,所以如果可能的话,每个厂商都提供了各自专用的解决方案。本文中,我将为PHPPostgreSQL提供一个解决方案。这个方案是基于标准特性的,所以它应该是很容易就能移植到任何语言/数据库中。

什么是BLOB?

BLOB是大二进制数据的缩写。它是指任何需要存入数据库的随机大块比特,例如图片或声音文件。这里的要点是BLOB是一个在数据库内部不能被翻译的对象。

PostgreSQL大对象

整件事开始于我需要将一些图形作为一个PHP Web应用程序的一部分存入一个PostgreSQL数据库。尽管PostgreSQL以Inversion Large Object(反转大对象)的形式提供了对BLOB的支持,但是你不能使用一般的SQL命令操控它们。PostgreSQL的大对象有自己的API,这在PHP里通过函数pg_locreatepg_loopenpg_lowritepg_loreadpg_loreadallpg_loclosepg_lounlink实现的。(见A

表A

函数

描述

pg_locreate

创建一个大对象并返回它的oid(对象身份)——一个用于区别PostgreSQL数据库实体的数字。

pg_loopen

在给定oid时,打开一个大对象,然后返回一个能在今后对它进行操控的filedescriptor

pg_lowrite

在给定文件描述符时,向一个打开的大数据库写入任意字节的数据。

pg_loread

在给定文件描述符时,从一个打开的大数据库读出任意字节的数据。

pg_loreadall

在给定文件描述符时,读出整个大的对象。

pg_loclose

选择先前打开的大对象。

pg_lounlink

在给出oid时,删除数据库里的大对象。

PostgreSQL大对象API

为了处理大对象,PostgreSQL提供了一个类似于文件I/O的独立API,前者在PHP里的是函数(详细情况见PHP/PostgreSQL文档)。

你必须存储由pg_locreate返回的对象身份标识(oid),通常是作为相关表的一列,以便于能够在今后访问这个大对象。PostgreSQL为此提供了一个数据类型(oid)。但是如果由于某些原因你丢失了大对象的oid,除了检查整个系统的表以找到它的oid就没有别的办法检索或者删除这个对象。这将是个很大的问题。

只要有一个清晰、没有错误的应用程序,这种情况通常是不会发生的。但是总会存在由于外部原因导致应用程序出错的危险,这会导致大对象的遗失。所以为了保险起见,一个规则的、清晰的程序是必需的。

另外一个关于PostgreSQL的解决方案问题是没有可以操控大对象的SQL命令,所以你必须编写脚本以执行甚至是最小的任务。这倒不是很麻烦,因为你的应用程序应该提供了所需的操作,但是我还是希望能够使用psql(PostgreSQL前端)来手动操控表和行。

一个标准的解决方案

将大对象作为表里的行来存储同时解决了这两个问题,因为事务处理保证了数据库的完整(没有查寻不到的大对象),而且表也可以通过SQL操控。但是SQL92标准没有为此定义任何合适的数据类型。

在SQL92标准定义的数据类型中,最好的选择是字符类型,它能存储变长串。但是,字符类型是为了存储字符而非二进制数据而设计的。尽管SQL92标准没有明确指出数据类型容量的限制,但是每个实际的产品都作出了上限。


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134