五月 22, 2023
摘要:在本文中,我们将看看 Oracle BLOB 是什么,以及如何将其转换到 PostgreSQL 并使用它。BLOB(二进制大对象)是一种 Oracle 数据类型,用于存储二进制数据(如文件内容)或信息(如音频、视频和图像)。PostgreSQL 没有直接的 BLOB 数据类型,但我们可以使用以下方法使用它。
大对象
大对象是存储在表外部的值。
假设您在 /tmp/ 文件夹下下载了一个图像(jpeg 格式):
$ ls /tmp/test.jpg
/tmp/test.jpg
我们希望将此图像存储在 PostgreSQL 数据库中。我们可以登录到数据库,执行下面的 SQL 语句:
postgres=# create table test1(n int,n1 oid);
CREATE TABLE
postgres=# insert into test1 values (1,lo_import('/tmp/test.jpg'));
INSERT 0 1
lo_import() 函数将命名文件加载到 pg_largeobject 中,并返回引用大对象的 OID(对象标识符)值。
选择表 test1 将显示 OID,而不是构成此照片的位。
目录 pg_largeobject(系统表)保存构成“大型对象”的数据。大型对象由创建时分配的 OID 标识。每个大对象都分为足够小的段,可以存储为 pg_largeobject 中的行。
每页的数据量是其 LOBLKSIZE(目前为 BLCKSZ / 4,或通常为 2 kB)。
postgres=# select * from test1;
n | n1
---+-------
1 | 16408
(1 row)
postgres=# select distinct loid from pg_largeobject;
loid
-------
16408
(1 row)
要查看当前数据库中的所有大对象,我们可以在 psql 终端中使用 “ \lo_list” 命令:
postgres=# \lo_list
Large objects
ID | Owner | Description
-------+----------+-------------
16408 | postgres |
(1 row)
使用函数 lo_export(),我们可以将照片写回文件中:
postgres=# SELECT lo_export( 16408, '/tmp/newtest.jpg' );
lo_export
-----------
1
(1 row)
使用差异实用程序比较两个文件:
$ diff /tmp/newtest.jpg /tmp/test.jpg
No difference found.
使用函数 lo_unlink(),您可以从数据库中删除大型对象:
postgres=# select lo_unlink(16408);
lo_unlink
-----------
1
(1 row)
postgres=# select * from pg_largeobject;
loid | pageno | data
------+--------+------
(0 rows)
Bytea 数据类型
bytea 数据类型可用于存储二进制字符串。bytea 的存储大小为 1 或 4 个字节加上实际的二进制字符串。
bytea类型支持I/O(输入)和O/P(输出)两种外部格式:即十六进制和转义格式。这两者都在输入时始终被接受。输出格式取决于称为 bytea_output 的 GUC 参数。此参数的默认值为 hex。
请参考 PostgreSQL 文档中的二进制数据类型,了解有关 bytea 数据类型和格式的更多信息。
假设您在 /tmp/ 文件夹下下载了一个图像(jpeg 格式):
$ ls /tmp/test.jpg
/tmp/test.jpg
我们希望将此图像存储在 PostgreSQL 数据库中。我们可以登录到数据库,执行下面的 SQL 语句:
postgres=# create table test(n int, n1 bytea);
CREATE TABLE
postgres=# insert into test values (1,'/tmp/test.jpg');
INSERT 0 1
postgres=# show bytea_output;
bytea_output
--------------
hex
(1 row)
postgres=# select * from test;
n | n1
---+------------------------------
1 | \x2f746d702f746573742e6a7067
(1 row)
postgres=# set bytea_output ='escape';
SET
postgres=# select * from test;
n | n1
---+---------------
1 | /tmp/test.jpg
(1 row)