我被要求向充满二进制数据的数据库(Oracle)添加可查询性。 所以我需要能够在几千字节的blob内查询二进制范围。我之前从未这样做过,所以我想知道在开始这样的项目时需要考虑哪些好的做法和陷阱。

由于

有帮助吗?

解决方案

添加一列MD5,它是BLOB数据的MD5校验和。或者,您可以使用相同的主键和MD5列创建新表。

数据库外部的缓存模块可以使用该列,而不必在缓存命中中检索BLOB列两次。

或者,您可以将BLOB数据放入数据库并将其存储在文件系统中,其中MD5值作为文件名,http服务器作为网络文件服务器。

其他提示

在不知道您的确切要求的情况下,我只能做一些一般性评论。

oracle中的BLOBS并不是最快速的类型。确保您不构建 许多性能瓶颈进入您的设计,并进行性能测试 您尽快构建的功能,以确保它符合要求。

dbms_lob是你的朋友。特别是你可能会发现read和substr函数(用于读取blob的部分)很有用。

远离外部C风格程序 - 它们可能会变慢。 PL / SQL函数往往要快得多。我不知道Java程序。作为java 引擎更集成到Oracle中,它们可能非常好用。这可能是值得的 做一个初步的概念证明,将PL / SQL与Java进行比较。

使用Java,您将能够以byte []流的形式读取数据并进行操作 使用Java世界来满足您的心灵需求。 Java的外部过程很容易 - 你甚至可以给Oracle提供Java源代码。

对于PL / SQL,我们发现一种非常有用的技术是将blob转换为raw,将其转换为 一个varchar,然后将其转换为十六进制,然后操纵十六进制(字符串) 使用标准的Oracle字符串函数。即:

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函数可以读取第一个<!> quot; byte <!> quot;通过substr(data, 1, 8),通过to_number(hexdata, 'xxxxxxxx')将其转换为小数,将其用作偏移...等等。

存储参数在存储和检索相对较小的BLOB(<!> lt; DB_BLOCK_SIZE * 2左右)时都会产生很大的差异。通常,您希望最小化行迁移和行链接,以及最大限度地减少浪费的可用空间。

对性能的最大影响可能是启用或禁用“IN ROW”存储 - 它绝对值得尝试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top