본문 바로가기

아이티/oracle&DB

DataType 중 Blob을 아세요...???

DataType 중 Blob을 아세요...???



Q : 음성파일과 동영상을 파일을 데이터베이스에 바로 저장하여 관리 할려고 합니다.. 그래서 Blob을 사용할려고 하는되요.. 디자인모드에서 DataType에 Blob은 없다고 나오네요.. 그래서 사용케 할려면 어케 해야 하는지.?? 그리고 long raw와 Blob에 차이점을 알고 계십니까? 그리고 사용방법을 알려주세요? 뭐.. 혹시 미디어파일을 관리해 보신분은 추천하고 싶은 파일관리법도 알려주시면 좋구요.. 그럼.. 오늘도 즐겁게 보내세요..'음성파일과 동영상을 파일을 데이터베이스에 바로 저장하여 관리 할려고 합니다..그래서 Blob을 사용할려고 하는되요..디자인모드에서 DataType에 Blob은 없다고 나오네요..그래서 사용케 할려면 어케 해야 하는지.??그리고 long raw와 Blob에 차이점을 알고 계십니까?그리고 사용방법을 알려주세요?뭐.. 혹시 미디어파일을 관리해 보신분은추천하고 싶은 파일관리법도 알려주시면 좋구요..그럼.. 오늘도 즐겁게 보내세요..



A :일단 제가 설명을 간단히 드리고 갈무리한 내용을 보시면 이해가 되리라 믿습니다.

지금 디비의 종류가 어떤것인지 잘 모르겟군요

sql server 인경우는 버젼 6.5 ,7.0 에 blob date type 이 지원이 됩니다.

oracle 인경우는 버젼 8i 부터 clob 과 blob이 지원 됩니다.

그전 버전인 경우는 long low로 저장을 해야 되지요

일단 동영상 화일과 같은 미디 화일도 이미지 저장 하는것과 일치 하신다고 생각
을 하십시요

저장하는 시점에 모든 자료을 한꺼번에 저장하는것이 아닌고 동영상 화일을 쪼개
서 저장을 하시다고 생각을 하시면 이해가 빠를겁니다.

아래의 내용은 갈무리한 내용입니다. 참조을 하시면 도움이 ...

DB에 그림을 넣을수 있는 방법은 각 DB마다 있어요.. 다만 각 DB마다 자료형을 다르게 하고 있죠.. 오라클 같은 경우 LOB이란 자료형이 있거든요...
그걸 이용해두 되구요.. 여러가지 방법이 있는데 모두 애기해줄수는 없구요..
그냥 오라클 예를 들어 보여줄게요.. 아마 설명을 읽으면 대충 어떤 식으로 저장이되는지 알수 있을겁니다....
인포믹스나 사이베이스 등 여러가지 DB회사도 이런 비슷한 자료형을 제공하거든요.. 사이트에 가서 한번 알아보세요..
모두 설명하기는 힘들구.. 많이 쓰는 오라클 하나만 보여주는거니까요..
설명이 잘 됐을래나 모르겠네요.. 즐거운 하루 되세요...
그럼 안뇽...
===================오라클에서 퍼온 자료 설명=====
LOB DATA TYPE의 이해
Bulletin no : 11395

< LOB DATA TYPE의 이해 >

1) 4 가지의 LOB TYPE

CLOB : Character LOB (1 byte character만 사용),
4Gig 보다 작은 data.
BLOB : Binary LOB, <= 4Gig.
NCLOB: National Character LOB (multibyte 로 구성된 national characterset)
<= 4Gig.

BFILE : Binary file로 DB 에 저장되는 것이 아니고 , O/S 에 저장

2) 사용하기

LOB 이 table 에 저장되어질때, data (LOB VALUE) 와 LOB_LOCATOR 라 불리는
pointer 가 분리되어 저장된다. 이는 같은 table 에 저장되어 질수도 다른
table 에 저장되어질수도 있다.

drop table test_lobs
/
drop directory tmp_dir
/
create table test_lobs (
c1 number,
c2 clob,
c3 bfile,
c4 blob
)
LOB (c2) STORE AS (ENABLE STORAGE IN ROW)
LOB (c4) STORE AS (DISABLE STORAGE IN ROW)
/

desc test_lobs

Name Null? Type
------------------------------- -------- ----
C1 NUMBER
C2 CLOB
C3 BINARY FILE LOB
C4 BLOB


<LOB storage 특성>

PCTVERSION - LOB data 가 update 시 read consistency 를 위해 old version 을
보관하기위해 사용하는 storage space 의 percent. 이는 default 값이 10 이다.

CHUNK - 한번의 read, write 를 통해 access하는 BLOB data 의 database block

CLOB,BFILE,BLOB column 을 같이 create 하는 table 은 BLOB column 의 data 는
항상 다른 row 에 저장되어야 한다.

몇개의 row 를 insert 해보자
empty_<lob>() function 은 해당 column LOB locator 를 generate 하는
constructor 의 역할을 한다.

이 locator 가 없이는 PL/SQL 에서 LOB data 를 access 할수 없다.


(1) 1 번째 row 를 insert
: locator 없는 입력

insert into test_lobs values (1,null,null,null)
/
(2) 2 번째 row 를 입력
:"null" locator 즉 locator 는 생성하나, pointer 는 아무런 값을 갖지
않는다. 그러나, BFILE 은 BFILENAME(null,null) 처럼 null directory 와
null file 을 이용해서 initialize 는 가능하나 empry locator 가 존재
하지 않는다.

insert into test_lobs values (2,EMPTY_CLOB(),null,EMPTY_BLOB())
/

(3) 3 번째 row 를 입력
: 4K까지 direct 하게 입력이 가능.
비록 locator 만 access 한다 하더라도 해당 data 까지 포함되게 되어있다.
BLOB 이 직접 insert 될때 string 은 hex 여야 하므로 HEXTOROW 가 행이
되던지 UTL_RAW.CAST_TO_RAW('the string') 를 call 해서 값이 covert
되도록 해야한다.
즉, '48656C6C6F' = 'Hello'이다.

insert into test_lobs values (3,'Some data for record 3.',
BFILENAME(null,null),'48656C6C6F'11 UTL_RAW.CAST_TO_RAW(' there!'))
/

(4) select 해보기

select * from test_lobs
/

SQL*Plus는 BFILE(null 이더라도)이나, BLOB의 data는 convert하지 못한다.

column c2 format a60 wrap
select c1, c2 from test_lobs
/

C1 C2
-------- --------------------------------------------------
1
2
3 Some data for record 3.

위의 경우 LOB locator 만 fetch 가 가능하고, 대응하는 data도 fetch가 가능
하다. 만일 3GL, PL/SQL을 사용하면 character string을 insert하나, 한 번에
select는 불가능하다.

예제)
declare
c_lob varchar2(10);
begin
c_lob := 'Record 4.';
insert into test_lobs values (4,c_lob,BFILENAME(null,null),
EMPTY_BLOB());
end;
/

작업완료 . 그러나,
--
declare
c_lob varchar2(10);
begin
select c2 into c_lob from test_lobs where c1 = 4;
end;
/

error message 가 다음과 같다. :

ERROR at line 4:
ORA-06550: line 4, column 19:
PLS-00385: type mismatch found at 'C_LOB' in SELECT...INTO statement
ORA-06550: line 4, column 4:
PL/SQL: SQL Statement ignored


(3) BFILE column을 설정하기

1. 이를 위해 맨 처음 BFILE 이 있는directory 의 handle 을 생성한다.

/tmp 에 4 줄의 rec2.txt를 생성한다.
/tmp 에 5 줄의 rec3.txt를 생성한다.

2. directory /tmp 의 ALIAS 를 생성한다.

create directory tmp_dir as '/tmp'
/

3. BFILE 의 관련 record 를 update 한다.


update test_lobs set c3 = BFILENAME('TMP_DIR','rec2.txt')
where c1 = 2
/
update test_lobs set c3 = BFILENAME('TMP_DIR','rec3.txt')
where c1 = 3
/


이들 column 은 oracle 의 READ-ONLY mode 로 관리되고 DBMS_LOB package 나
OCI 를 통해 access 가 가능하다.


<DBMS_LOB 사용하기>


LOB data 의 length 를 구하기.
empty locator 가 specify 된 곳의 length 는 0 이다.

column len_c2 format 9999
column len_c3 format 9999
column len_c4 format 9999

select c1, DBMS_LOB.GETLENGTH(c2) len_c2, DBMS_LOB.GETLENGTH(c3) len_c3,
DBMS_LOB.GETLENGTH(c4) len_c4
from test_lobs
/


C1 LEN_C2 LEN_C3 LEN_C4
---------- ------ ------ ------
1
2 0 172 0
3 23 248 12
4 9 0


SUBSTR/INSTR 사용 :CLOB, BLOB , BFILE은 모두 사용가능하나BFILE 을 위해
file 은 미리 open 되어 있어야 한다.

SUBSTR parameter 는 LOB, amount, offset 이다.이는 기존의 substr function
과는 반대이다.
INSTR 는 LOB, string, offset, occurence,(offset, occurrence 가 생략시 1)
이다.

column sub_c2 format a10
column ins_c4 format 99
select c1, DBMS_LOB.SUBSTR(c2,9,3) sub_c2,
DBMS_LOB.INSTR(c4,UTL_RAW.CAST_TO_RAW('ello'),1,1) ins_c4
from test_lobs
/

C1 SUB_C2 INS_C4
---------- ---------- ------
1
2 0
3 me data f 2
4 cord 4. 0

다음은 PL/SQL block 에서 DBMS_LOB 을 사용하는 것을 보여준다.

set serveroutput on
set long 1000
declare
b_lob BLOB;
c_lob CLOB;
c_lob2 CLOB;
bf BFILE;
buf varchar2(100) :=
'This is some text to put into a CLOB column in the' 11
chr(10) 11'database. The data spans 2 lines.';
n number;
fn varchar2(50); --Filename
fd varchar2(50); --Directory alias


/* 다음의 procedure는 한번에 1line을 print하는 것을 보여준다 */

procedure print_clob is
offset number;
len number;
o_buf varchar2(200);

amount number; --}
f_amt number := 0; --}To hold the amount of data
f_amt2 number; --}to be read or that has been
amt2 number := -1; --}read


begin
len := DBMS_LOB.GETLENGTH(c_lob);
offset := 1;
while len > 0 loop
amount := DBMS_LOB.INSTR(c_lob,chr(10),offset,1);

--Amount returned is the count from the start of the file,
--not from the offset.
if amount = 0 then
--No more linefeeds so need to read remaining data.
amount := len;
amt2 := amount;
else
f_amt2 := amount; --Store position of next LF
amount := amount - f_amt; --Calc position from last LF
f_amt := f_amt2; --Store position for next time
amt2 := amount - 1; --Read up to but not the LF
end if;
DBMS_LOB.READ(c_lob,amt2,offset,o_buf);
dbms_output.put_line(o_buf);
len := len - amount;
offset := offset+amount;
end loop;
end;

address(주소)가 땀삐질^^;;