2009.12.01
about CUBRID schema in CUBRID query in CUBRID caching in CUBRID
CUBRID 소개 오픈소스라이선스데이터베이스 인터넷서비스최적화지향 대용량데이터베이스및 64bit 지원 HA 및복제지원 테이블분할지원 질의수행계획, 결과캐쉬 ( 서버 / 클라이언트 ) JAVA 기반의 stored procedure GUI 기반의관리 / 질의수행도구 (CUBRID manager)
CUBRID 소개 ( 계속 ) 5. 라이선스 / 서비스정책 오픈소스라이선스소개 Interfaces ODBC OLEDB JDBC PHP CCI Python Ruby CUBRID Manager Client(GUI) New BSD 수정 / 배포시공개의무없음 Job Queuing Query Parser Optimizer Monitoring / Logging Lock Caching Connection Pooling Brokers CUBRID Manager Server GPL V2 수정후배포시 GPL 로공개 Database Server Object Manager Transaction Manager Query Manager Lock Manager Storage Manager Log Manager Utilities (Backup/Restore/ Compact/Check/ Lock..)
CUBRID 소개 ( 계속 ) 5. 라이선스 / 서비스정책 CUBRID 구조
CUBRID 스키마 테이블 개수무제한 이름에한글, 영문자, 숫자, _, #, % 사용가능, 첫글자는문자 ( 영문, 한글 ) 이름최대길이는 255자, 대소문자구분없음 컬럼 테이블당최대 6,400 개생성가능 이름에한글, 영문자, 숫자, _, #, % 사용가능, 첫글자는문자 ( 영문, 한글 ) 이름최대길이는 255자, 대소문자구분없음 index 테이블당최대 6,400 개생성가능 이름지정가능 제약조건 NULL: NULL 값을허용 NOT NULL : NULL 값을허용하지않음 unique : 중복된값허용하지않음, default 와같이선언불가 primary key / foreign key 예약어사용시 로감싸주어야함. 예 ) date 데이터베이스이름최대길이 : 128 자, 대소문자구분
CUBRID 저장 구조 저장 단위 page : 2Kb, 4Kb(default), 8Kb, 16Kb, 32Kb 변경 불가, 데이터베이스내 동일 크기 block ORACLE 볼륨 : 데이터베이스 저장 공간 GENERIC, DATA, INDEX, TEMP 테이블 스페이스 ORACLE
CUBRID 스키마 테이블 개수무제한 이름에한글, 영문자, 숫자, _, #, % 사용가능, 첫글자는문자 ( 영문, 한글 ) 이름최대길이는 255자, 대소문자구분없음 컬럼 테이블당최대 6,400 개생성가능 이름에한글, 영문자, 숫자, _, #, % 사용가능, 첫글자는문자 ( 영문, 한글 ) 이름최대길이는 255자, 대소문자구분없음 index 테이블당최대 6,400 개생성가능 이름지정가능 제약조건 NULL: NULL 값을허용 NOT NULL : NULL 값을허용하지않음 unique : 중복된값허용하지않음, default 와같이선언불가 primary key / foreign key 예약어사용시 로감싸주어야함. 예 ) date 데이터베이스이름최대길이 : 128 자, 대소문자구분 db_root dual
CUBRID 스키마 ( 계속 ) 논리형 boolean: 지원않함 문자형 byte단위처리 입력되는 codeset 유지 내부적으로 codeset 지정하지않음 char: 고정길이형 다른컬럼과같이저장 길이가일정하거나인덱스로사용될때 select시 rtrim() 필요 varchar: 가변길이형 최대1G(string) LONG, CLOB ORACLE 다른컬럼과다른곳에저장 데이터길이와저장된위치에대한포인터저장에대한 overhead update시길이변하는경우 overhead
CUBRID 스키마 ( 계속 ) 숫자형 smallint: 2bytes, -32768 ~ 32767 integer: 4bytes, -2147483648 ~ 2147483647 bigint: 8bytes, -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 numeric: numeric(10), numeric(10,2), numeric(38) number ORACLE float:-10e38 ~ 10e38, 유효자리수초과하는수치정밀도보장불가 double:-10e308 ~ 10e308, float 와마찬가지로유효자리수문제 Binary data GLO: CUBRIDOID in JAVA, etc BIT Varying : FileInputStream in JAVA BLOB ORACLE
CUBRID 스키마 ( 계속 ) 날자 / 시간형 값허용않함, NULL 또는표현가능한값입력허용 date: 날자만저장, 기본형 mm/dd/yyyy time: 시간만저장, 기본형 hh:mi:ss datetime: 1/100 초, mm/dd[/yyyy] hh:mi[:ss.ff] 또는 [yyyy-]mm-dd hh:mi[:ss.ff] timestamp:1970/1/1 09:00:00 이후경과한초, 최대 2038/1/19 03:14:07 to_char() 등사용시인덱스사용불가, 상수사용시기본형사용권장 예 ) where reg_date = 12/25/2009 and reg_time = 18:32:50 NULL is not (empty string) string_field = string_field is null string_field is not null string_field = null ( 결과예상못함 ) 엄격한데이터형비교 where 1 = 1 : 에러 select 1 + 1 : 에러
CUBRID 스키마 ( 계속 ) 테이블생성 create table 명령이용 테이블복제 : 테이블생성후 insert select 수행 storage 관련 option 지원않함. create table < 테이블이름 > [ ( 컬럼정의절 [, {, 컬럼정의절 }] ) ] 컬럼정의절 : 컬럼이름데이터타입 [default 값 ] [ 제약사항 ] 데이터타입 : int, bigint, char, varchar, numeric, date, time, timestamp, datetime 제약사항 : primary key, foreign key, not null, null, unique, check( 지원않함 ) 예 ) create table my_company ( comp_id int not null unique, comp_name varchar(100) default, seq_no int auto_increment not null, // not null 과 auto increment 순서주의 est_date date default systime // table 생성시점이 default 값으로사용됨 )
CUBRID 스키마 ( 계속 ) 테이블변경 alter table 명령이용 rename table < 테이블이름 > as < 새테이블이름 > alter table < 테이블이름 > add atrribute < 필드명 > < 필드타입 > [ 속성 ] alter table < 테이블이름 > rename attribute < 필드명 > as < 새필드명 > alter table < 테이블이름 > change < 필드명 > default < 새값 > alter table < 테이블이름 > drop attribute < 필드명 > 필드타입변경 새테이블생성을통한변경 : 필드순서유지 create table < 새테이블 > (< 새타입을가지는필드를포함한필드정보들 >) insert into < 새테이블 > select from < 이전테이블 > // 필요한경우 cast() 등사용 drop table < 이전테이블 > rename table < 새테이블 > as < 이전테이블 > 새필드생성을통한변경 : 필드순서변경됨 alter table < 테이블 > add attribute < 새필드 > < 새로운필드타입 > update < 테이블 > set < 새필드 > = < 필드 > // 필요한경우 cast() 등사용 alter table < 테이블 > drop attribute < 필드 > alter table < 테이블 > rename attribute < 새필드 > as < 필드 >
CUBRID 스키마 ( 계속 ) primary key 테이블생성시, 생성후추가가능 이름지정가능하며, default : pk_< 테이블이름 >_< 필드명 >[_< 필드명 > ] create table my_table ( id int primary key ) create table my_table2 ( id int, primary key(id) ) create table my_table3 ( id int, constraint pk1 primary key(id) ) alter class my_table drop constraint pk_my_table_id alter class my_table add constaint pk1 primary key(id)
CUBRID 스키마 ( 계속 ) foreign key 테이블생성시, 생성후추가가능 이름지정가능하며, default : fk_< 테이블이름 >_< 필드명 >[_< 필드명 > ] create table f_table ( id int foreign key references my_table(id) ) create table f_table2 ( id int, foreign key(id) references my_table2(id) ) create table f_table3 ( id int, constraint fk1 foreign key(id) references my_table3(id) ) alter class f_table drop constraint f_f_table_id alter class f_table add constaint fk1 foreign key(id) references my_table1(id)
CUBRID 스키마 ( 계속 ) foreign key options 참조하는기본키의수정, 삭제에대한제한 on update : restrict(default), no action on delete : restrict(default), cascade, no action on cache object : CUBRID 에서만제공, 개체개념접목 참조하는테이블을타입 ( 사용자정의타입 ) 으로하는필드추가 추가되어지는필드의데이터는데이터베이스엔진이관리 간편한검색제공, outer join create table company ( comp_id int primary key, comp_name varchar(100), ) create table client ( comp_id int, foreign key (comp_id) references company(comp_id) on update restrict on delete cascade on cache object comp_oid ) select client_name, co.comp_name from client cl, company co where cl.comp_id = co.comp_id 홍길동, NHN select client_name, co.comp_name from client cl, company co where cl.comp_id = co.comp_id(+) 홍길동, NHN 홍길순, NULL select client_name, comp_oid.comp_name from client 홍길동, NHN 홍길순, NULL
CUBRID 스키마 ( 계속 ) index 인덱스이름지정가능 생성시필드별오름차순, 내림차순지정가능 unique index, reverse index( 모든필드내림차순 ) primary key, foreign key 도 index 를통한관리 별도생성필요없음 create index on my_table(id, name) create unique index idx1 on my_table(id) create index idx on my_table(id, name desc) create revese index r_idx on my_table(name)
CUBRID 스키마 ( 계속 ) 스키마조작제한 스키마관련명령어 (DDL) 수행제한 서비스운영중스키마조작제한을통한서비스안정화 CUBRID 설정화일 (cubrid.conf) 상의설정값조정 block_ddl_statement=yes CUBRID broker 재구동을통한설정반영
CUBRID 스키마 ( 계속 ) 시스템카다로그 스키마정보를보관한시스템테이블 질의를통한스키마정보조회 테이블정보 db_class 주요필드 : class_name, owner_name 컬럼정보 기타 db_attribute 주요필드 : class_name, attr_name, attr_type db_vclass db_index db_index_key db_trig db_partition db_stored_procedure db_auth
CUBRID 질의 SQL-2 (SQL92) 표준 예약어사용시 로감싸주어야함. 입력 insert into < 테이블이름 > [( < 필드목록 > )] values( < 값목록 > ) insert into < 테이블이름 > select from 수정 update < 테이블이름 > set < 필드명 > = < 값 > [, ] [where ] update < 테이블이름 > set ( < 필드명 >,< 필드명 > [, ] ) = (select < 필드명 >,< 필드명 > [, ] from ) [where ] 삭제 delete from < 테이블이름 > [ where ]
CUBRID 질의 ( 계속 ) 조건없는수정 / 삭제제한 where 절없는 update, delete 수행제한 서비스운영중관리자혹은응용실수로인한전체데이터수정, 삭제제한을통한서비스안정화 CUBRID 설정화일 (cubrid.conf) 상의설정값조정 block_nowhere_statement=yes CUBRID broker 재구동을통한설정반영
CUBRID 질의 ( 계속 ) 검색 sub-query 지원 where (a,b) in (select ) 연산자 =, <>, >=, <= +, -, *, /, CONCAT in ORACLE 집합연산자 UNION, UNION ALL, DIFFERENCE(MINUS in ORACLE), INTERSECTION(INTERSECT in ORACLE) 양쪽 select 절필드타입이동일해야함 (casting 필요 ) outer join char union varchar varchar int union numeric numeric left outer, right outer join group by select from class1 a left outer join class2 b on a.name = b.name select from class1 a, class2 b where a.name = b.name(+) select a, to_char(d, YYYY/MM/DD ), count(*) from my_table group by a, to_char(d, YYYY/MM/DD )
CUBRID 질의 ( 계속 ) 인덱스힌트 질의수행시사용할인덱스지정 지정된인덱스만사용, 지정하지않은인덱스는없는것으로간주 지정한인덱스와 full scan 중비용이낮은것선택 조인시필요한인덱스모두지정, 서브질의는상관없슴 (+) 이용하여인덱스사용 cost를 0 으로강제 select * from my_table where a = 1 using index NONE select * from my_table where a = 1 using index idx1 select * from my_table where a = 1 using index idx1(+) select * from my_table m, my_table2 t where m.a = 1 and m.b = t.b using index m.idx1, t.idx1
CUBRID 질의 ( 계속 ) 조인힌트 테이블간조인시조인방법, 순서지정 select 절다음에 /*+ */ 사이에지정 조인방법 USE_IDX : 조인시인덱스사용 USE_NL : 조인시 nested loop 조인사용 USE_MERGE : 조인시 sort merge 조인사용 조인순서지정 ORDERED : from 절에명시된순서대로조인, order by 회피 select /*+ USE_IDX */ from my_table m, my_table2 t where select /*+ USE_IDX(t) */ from my_table m, my_table2 t, my_table3 e where select /*+ ORDERED */ from my_table, my_table2 where
CUBRID 질의 ( 계속 ) serial 일련번호생성 트랜잭션의영향받지않음 sequence ORACLE create serial seq_no select seq_no.current_value from db_root insert into bbs( ) values(seq_no.nextval, ) alter serial seq_no start_with 100 auto increment 레코드입력시필드값자동증가 serial 을이용한관리 최종증가된현재값확인가능, 세션에영향받지않음 create table my_table ( t_no int auto_increment ) create table my_table2 ( t_no int auto_increment(11, 2) ) select my_table_ai_t_no from db_root
CUBRID 질의 ( 계속 ) rownum 검색결과레코드에대한일련번호부여 order by, group by 실행전에 rownum 부여 select rownum, id from bbs where rownum between 11 and 20 select id from bbs where rownum between 11 and 20 group by id select id from bbs where inst_num() between 11 and 20 group by id select rownum, id from bbs where rownum between 11 and 20 order by id select orderby_num(), id from bbs order by id for orderby_num() between 11 and 20
CUBRID 질의 ( 계속 ) rownum 을이용한페이징방법 seq_no 에대하여최근번호를우선으로해서 11번째부터 10개가져옴 select seq_no from bbs order by seq_no desc limit 11, 10 select seq_no from bbs order by seq_no desc for orderby_num() between 11 and 20 인덱스와 rownum 을이용하여질의조정 인덱스를이용하여결과를가져오면인덱스순서대로결과를가져옴 조건이있어야인덱스사용, 모든값이나오도록조건추가 using index (+) 를이용하여인덱스사용하도록지정 create index r_idx on bbs(seq_no desc) select seq_no from bbs where seq_no > () and rownum between 1 and 10 using index r_idx(+)
CUBRID 질의 ( 계속 ) click counter 주어진필드의값을 1만큼증가 select, update 질의를 select 질의만으로수행 incr() : 현재값을넘겨주고, 그값을 1만큼증가시킴 select seq_no, incr(read_cnt) from bbs count(*) 성능개선 인덱스를이용한 count create table my_table ( id int primary key ) select count(*) from my_table select count(*) from my_table where id > 0 using index pk_my_table_id(+)
CUBRID 질의 ( 계속 ) 파티션 range, list, hash 지원 개별파티션조회가능 create table cal ( yy int ) partition by range(yy) ( partition r_1900 values less than(2000), partition r_2000 values less than(3000), partition r_etc values less than maxvalue ) create table zip ( city char(20) ) partition by list(city) ( partition l_city0 values in ( 서울, 부산 ), partition l_city1 values in (NULL, 경기도 ) ) create table log ( user_id char(20) ) partition by hash(user_id) partitions 8
CUBRID 질의 ( 계속 ) 함수 문자열 수학 length(), trim(), pad(), substr(), instr(), replace(), etc ascii(), soundex(), translate() : 지원않함 abs(), sign() random(), drandom(), rand(), drand() DBMS_RANDOM.VALUE in ORACLE sin(), sinx() 계열 : 지원않함
CUBRID cache 질의수행계획캐쉬 질의수행시생성되는질의수행계획캐쉬 동일한질의수행시캐슁된질의수행계획사용으로질의수행계획생성시간절약을통한성능향상 약 30% 성능향상 환경설정 (cubrid.conf) max_plan_cache_entries 쿼리플랜을캐쉬에저장하도록설정하는파라미터 0 보다큰값일경우설정값만큼의퀴리플랜을캐쉬에저장 default 값은 1000 으로 1000 개의질의에대한질의수행계획을캐쉬에저장 캐쉬를사용하지않고질의수행계획을질의수행시생성하도록설정 질의에 /*+ RECOMPILE +/ 사용 select /*+ RECOMPILE */ * from record where
CUBRID cache ( 계속 ) 질의결과캐쉬 동일한사용자의동일한질의에대하여질의수행결과를캐쉬 질의플랜캐쉬설정시사용가능 max_plan_cache_entries >= 1 동일한질의수행시질의를재수행하지않고캐쉬된결과를이용함으로써수행성능향상 검색위주의시스템에유용 일반적인업무 ( 입력 / 수정 / 삭제가빈번한경우 ) 의경우캐쉬내용업데이트에따른 over-head 증가로인한성능감소가능 질의결과캐쉬되지않는경우 sys_date, current_time, current_user 와같이질의수행시마다값이변하는함수가사용된경우 method, JAVA stored procedure 가사용된경우 prepare 단계에서 host 변수에대한 data type 을알아내기어려운경우 질의수행계획캐쉬가갱신되는경우 /*+ RECOMPILE +/ 사용시
CUBRID cache ( 계속 ) 질의결과캐쉬환경설정 (cubrid.conf) max_query_cache_entries 캐쉬에저장할질의수행결과의최대개수 -1(default): 사용하지않음 query_cache_mode 질의결과캐쉬방법설정 1 : 모든질의에대하여결과캐쉬 2 : 질의상에명시 (/*+ QUERY_CACHE(1) */) 된질의만결과캐쉬 select /*+ QUERY_CACHE(1) */ * from
CUBRID cache ( 계속 ) client cache JDBC 를통한질의수행결과를 CUBRID Broker 에캐쉬 환경설정 (cubrid_broker.conf) jdbc_cache default 는 0 으로, 0 인경우캐쉬하지않는다. 1 일경우질의수행결과를캐쉬한다. jdbc_cache_only_hint jdbc_cache 가 1 일경우유효함. default 는 0 이며, 모든질의에대하여캐쉬한다. 1 일경우질의힌트에캐쉬가명시된경우에만캐쉬한다. jdbc_cache_life_time 캐쉬의유효시간을 ms 단위로설정 질의상의힌트설정 /*+ JDBC_CACHE */ : 캐쉬를사용하고, jdbc_cache_life_time 동안유효함 /*+ JDBC_CACHE(life_time) */ : 캐쉬를사용하고, 주어진 life_time 동안유효함