oracle二进制数据类型

Sau*_*s S 4 sql oracle oracle11g

是否有一种类型或方式如何在二进制级别的oracle中存储数据.我对表中的dml和pl/sql的操作感兴趣.

目前,所有二进制元素都存储为varchar2(1000)='11111 ... 0000.1111',但操作和数据存储大小相当大,因此需要一些优化解决方案.如果这些数据可以以二进制格式存储,则需要1000/8字节(具有> 700mln记录)

也许解决方案是使用某种java + oracle组合进行这些操作.

欢迎提出意见和建议.

Vin*_*rat 8

如果要存储最多4000个字节的二进制数据,请使用RAW数据类型.数据将存储为字符串而不进行字符集转换.

使用UTL_RAW包来执行操作RAWs.

不推荐使用LONG RAW数据类型,当需要处理超过4000个字节的数据时,应切换到BLOB.


spe*_*593 6

请参阅Vincent Malgrat的回答:如果要在Oracle中存储和处理二进制数据,那么RAW数据类型就是最佳选择.

(正如alegen的回答所暗示的,如果您的意图是存储和检索图像,视频,音频或压缩数据,这些数据不需要在数据库中"处理",但您只是"存储"它并"检索"它,那么BLOB数据类型可能更合适;

(注意:RAW数据类型限制为4000字节,BLOB数据类型不是.出于性能原因,我更倾向于将RAW用于更短(例如,200字节或更少)的值,我需要定期访问对于更长的值,在很多查询没有引用二进制数据的情况下,我倾向于支持BLOB.(这都是由于内部存储的方式不同RAWBLOB存在:内联存储与单独的块,分割行,适合块的行数等)

对于您描述的特定问题,根据您提供的信息,然后RAW听起来像是要走的路.您指定您有1000位的序列,但是它是否是常量或最大长度,或者您是否已将更长的二进制数据字符串分解为更适合列的可管理块,这一点都不清楚.(如果你真的在使用一大块二进制数据,那么你真的想避免将它"切碎"成一堆小块,并将每一块存储在一个单独的行上.这样做会更有效率.将它们作为单个BLOB存储在一起,并将其作为简单流进行处理.

所有这些都将真正告知您是否使用BLOB或RAW的决定.


除此之外,关于转换从1和0的VARCHAR2表示(例如'00101010',将每个"位"的真实信息存储为单独的字符)转换为更有效存储的二进制表示,每个"8位" "需要一个字节的存储的真实信息......

Oracle RAW数据类型将使您将8位存储到单个字节中.也就是说,RAW(125)将存储VARCHAR2(1000)的等效值,这将为每行节省875个字节(对于SBCS,如果使用DBCS,则为两倍以上).这将显着降低存储要求,在块中获得更多行,并允许更好的性能.

要将当前存储的数据转换VARCHAR2为1和0的字符串,我不知道有任何内置函数可以做到这一点.但是滚动自己的函数将二进制字符串表示转换为十六进制字符串表示是相当简单的.之后,您可以使用内置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
Run Code Online (Sandbox Code Playgroud)

注意:此函数仅在输入字符串的长度为8(即MOD(length(as_binstr),8) = 0)的偶数倍时返回预期结果(匹配的十六进制表示).否则,函数"丢失"尾随位和/或返回奇数个十六进制数字.(当输入参数的长度不是8的倍数时,可以修改该函数以引发异常.)

使用客户端应用程序(如TOAD,SQL Developer或SQL*Plus)处理数据时,HEXTORAWRAWTOHEX函数非常有用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;
/
Run Code Online (Sandbox Code Playgroud)

正如Vincent Malgrat在他的回答中指出的那样,Oracle提供了一些在处理RAW数据时很有用的软件包(例如UTL_RAWUTL_ENCODE).

http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/u_raw.htm