我被要求向一个主要填充二进制数据的数据库 (Oracle) 添加可查询性。所以我需要能够查询几千字节的 blob 内的二进制范围。我以前从未这样做过,所以我想知道在开始这样的项目时要考虑哪些好的做法和陷阱。
谢谢
我被要求向一个主要填充二进制数据的数据库 (Oracle) 添加可查询性。所以我需要能够查询几千字节的 blob 内的二进制范围。我以前从未这样做过,所以我想知道在开始这样的项目时要考虑哪些好的做法和陷阱。
谢谢
添加一列MD5,即BLOB数据的MD5校验和。或者,您可以创建一个具有相同主键和 MD5 列的新表。
Your cache module outside the database can make use of that column not to have to retrieve the BLOB column twice in a cache-hit.
OR, you could drop the BLOB data in the database and store it in a file system with the MD5 value as a filename with an http server as a network file server.
在不知道您的确切要求的情况下,我只能发表一些一般性评论。
oracle 中的 BLOBS 不是最快速的类型。确保您不会在设计中构建许多性能瓶颈,并尽快对您构建的功能进行性能测试,以确保其满足要求。
dbms_lob 是你的朋友。特别是您可能会发现 read 和 substr 函数(用于读取 blob 的一部分)非常有用。
远离外部 C 风格的程序——它们可能会很慢。PL/SQL 函数往往要快得多。我不知道Java程序。由于 Java 引擎更多地集成到 Oracle 中,因此它们可能非常好用。将 PL/SQL 与 Java 进行比较可能值得做一个初步的概念证明。
使用 Java,您将能够以字节 [] 流的形式读取数据,并使用 Java 的世界将其操作到您心中的内容。Java 的外部过程很容易实现——您甚至可以将 Java 源代码提供给 Oracle。
对于 PL/SQL,我们发现一种非常有用的技术是将 blob 转换为 raw,将其转换为 varchar,然后将其转换为十六进制,然后使用标准的 Oracle 字符串函数处理十六进制(字符串)。IE:
create or replace function retrieve_data_from_blob (
b blob
, tag_code
)
as
lw long raw;
data varchar(30000);
result varchar(100);
amount pls_integer := 30000;
begin
-- covert blob to long raw.
-- amount will hold total bytes read.
dbms_lob.read(b, amount, 1, lw);
data := util_raw.rawtohex(lw);
-- retrieve_embedded retrieves data tagged with tag_code
-- from internal binary structure by reading hex data
return retrieve_embedded(data, tag_code);
end;
/
这适用于大小不超过 15Kb 的 blob。例如,retrieve_embedded 函数可以通过执行 a 读取第一个“字节”,通过将其用作偏移量substr(data, 1, 8)
将其转换为十进制......等等。to_number(hexdata, 'xxxxxxxx')
当涉及到存储和检索相对较小的 BLOB(< DB_BLOCK_SIZE * 2 左右)时,存储参数可以产生相当大的差异。通常,您希望尽量减少行迁移和行链接,以及尽量减少浪费的可用空间。
也许对性能的最大影响是启用或禁用“IN ROW”存储——这绝对值得一试。