请参阅 Vincent Malgrat 的回答:如果您想在 Oracle 中存储和处理二进制数据,那么 RAW 数据类型是您的最佳选择。
(正如 alegen 的回答所暗示的那样,如果您的意图是存储和检索不需要在数据库中“处理”的图像、视频、音频或压缩数据,但您只是“存储”它并且“检索”它,那么BLOB 数据类型可能更合适;
(注意:RAW 数据类型限制为 4000 字节,BLOB 数据类型不是。出于性能原因,我更喜欢将 RAW 用于更短的值(例如,200 字节或更少),我需要定期访问值。对于更长的值,很多查询没有引用二进制数据,我倾向于支持BLOB。(这完全是由于RAW和BLOB的方式不同内部存储:内联存储与单独的块、拆分行、适合块的行数等)
对于您描述的特定问题,根据您提供的信息,RAW 听起来像是要走的路。您指定您有 1000 位的序列,但完全不清楚这是一个常数,还是一个最大长度,或者您是否已将较长的二进制数据字符串分解成更易于管理的块,这些块将适合列。 (如果你真的在处理一个单一的、巨大的二进制数据块,你真的希望避免将它“切割”成一堆小块,并将每一块存储在单独的行中。这样会更有效率将它们全部存储为单个 BLOB,并将其作为简单的流使用。
所有这些都会真正帮助您决定是使用 BLOB 还是 RAW。
除此之外,关于您关于从 VARCHAR2 表示的 1 和 0(例如,'00101010',将真实信息的每个“位”存储为单独的字符)转换为更有效地存储的二进制表示的问题,每个“ 8 位”的真实信息需要一个字节的存储空间......
Oracle RAW 数据类型会将 8 位存储到单个字节中。也就是说,RAW(125) 将存储您的 VARCHAR2(1000) 的等价物,这将为您每行节省 875 个字节(对于 SBCS,如果您使用的是 DBCS,则是两倍多)。这将显着降低存储需求,让您在一个块中获得更多行,并有可能获得更好的性能。
要将当前存储为VARCHAR2 的数据转换为一串一和零,我不知道有任何内置函数可以做到这一点。但是滚动您自己的函数将二进制字符串表示形式转换为十六进制字符串表示形式是相当简单的。之后,您可以使用内置的HEXTORAW 函数转换为RAW。
这是一个可以作为起点的示例。
(注意:这个函数只是一个例子,当输入字符串的长度不是 8 个字符的倍数时,它不能有效地处理情况。此外,它的行为是字符串值包含除 '1' 或“0”可能不合适(正如它所写的那样,它将“0”以外的任何字符都视为“1”。但是,作为起点已经足够了)。
create or replace function binstr_to_hexstr
( as_binstr in varchar2 ) return varchar2
is
li_n binary_integer default 0;
ls_hexstr varchar2(16) default '0123456789ABCDEF';
ls_return varchar2(2000) default '';
begin
if ( as_binstr is null ) then
return null;
end if;
ls_return := '';
li_n := 0;
for i in 1 .. length(as_binstr) loop
li_n := li_n*2 + abs(instr('01',substr(as_binstr,i,1))-1);
if mod(i,4) = 0 then
ls_return := ls_return || substr(ls_hexstr,li_n+1,1);
li_n := 0;
end if;
end loop;
return ls_return;
end;
/
SELECT binstr_to_hexstr('00101010') AS hexstr FROM DUAL UNION ALL
SELECT binstr_to_hexstr('00x0 010') FROM DUAL;
HEXSTR
------
2A
2A
注意:仅当输入字符串的长度是 8 的偶数倍(即MOD(length(as_binstr),8) = 0)时,此函数才会返回预期结果(匹配的十六进制表示)。否则,函数“丢失”尾随位和/或返回奇数个十六进制数字。 (该函数可以修改为当输入参数的长度不是8的倍数时抛出异常。)
HEXTORAW 和 RAWTOHEX 函数在使用客户端应用程序(例如 TOAD、SQL Developer 或 SQL*Plus)处理 RAW 数据时非常有用。 (HEXTORAW 函数用于将 binstr_to_hexstr 函数的输出转换为 RAW。)例如:
create or replace function binstr_to_raw
( as_binstr in varchar2 ) return raw
is
begin
return hextoraw(binstr_to_hexstr(as_binstr));
end;
/
正如 Vincent Malgrat 在他的回答中指出的那样,Oracle 提供了几个包(例如 UTL_RAW 和 UTL_ENCODE),它们对于处理 RAW 数据很有用。
http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/u_raw.htm