mysql -u root -p

패스워드 입력 후 

GRANT ALL PRIVILEGES ON *.* TO 'id'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;

GRANT ALL PRIVILEGES ON *.* TO 'id'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

flush privileges;

형식으로 유저 추가 

d dbid cid 
ahn 116421 Aggie 
ahn 116432 Annes 
ahn 116443 Aqeee 
akxkf 118461 강11 
akxkf 118462 강22 
akxkf 118463 강44 
akxkf 118464 강55 

이 데이터 에서 
같은 id중에서 cid를 알파벳 순으로 정렬 
시킨 후 가장 위에 것만 가져 오는 쿼리

WITH TEMP AS 

SELECT 'ahn' AS ID, '116421' AS DBID, 'Aggide' AS CID FROM DUAL UNION ALL 
SELECT 'ahn' AS ID, '116432' AS DBID, 'Annes' AS CID FROM DUAL UNION ALL 
SELECT 'ahn' AS ID, '116443' AS DBID, 'Aqeee' AS CID FROM DUAL UNION ALL 
SELECT 'akxkf' AS ID, '118461' AS DBID, '강11' AS CID FROM DUAL UNION ALL 
SELECT 'akxkf' AS ID, '118462' AS DBID, '강22' AS CID FROM DUAL UNION ALL 
SELECT 'akxkf' AS ID, '118463' AS DBID, '강44' AS CID FROM DUAL UNION ALL 
SELECT 'akxkf' AS ID, '118464' AS DBID, '강55' AS CID FROM DUAL 

SELECT * 
FROM ( 
SELECT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY CID) AS CHK 
, ID 
, DBID 
, CID 
FROM TEMP 
) A 
WHERE A.CHK = 1
 

'Oracle/Mysql/Sql' 카테고리의 다른 글

Mysql User 추가  (0) 2013.04.09
CAP Theorem  (0) 2011.06.28
두테이블을 비교해서 같지않은 값만 출력하기  (0) 2011.05.23
계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
웹이 점점 커지고 다양한 요구가 생겨나는 가운데 NoSQL이 커다란 이슈중에 하나로 떠오르고 있습니다. 제가 NoSQL에 대해서 처음 들은 것은 올 초정도로 기억하고 있습니다.

Google Trends에서 NoSQL로 검색한 결과

구글 트랜즈   에서 확인해보아도 NoSQL이라는 단어가 이슈화되기 시작한 것은 2009년 중순정도로 나타나고 있습니다.  위키피디아   에서 확인해 보면 NoSQL이라는 단어는 1998년 Carlo Strozzi이 SQL을 드러내지 않는 경량 데이터베이스로 이름지었고 2009년 초에 Last.fm   의 Johan Oskarsson이 오픈소스 분산데이터베이스에 대한 논의를 위한 이벤트를 원했을 때 Rackspace   의 직원인 Eric Evans가 NoSQL이라는 단어를 다시 소개했다고 합니다. 아틀란타에서 열린 no:sql conference 2009가 NoSQL논의에 큰 영향을 미쳤다고 합니다. (이 컨퍼런스의 모토인 "select fun, profit from real_world where relational=false;"가 상당히 센스넘치는군요)

올해 중에 NoSQL중 하나는 경험해 보자는 생각이었는데 마침 좀 만져볼 기회가 생겨서 좀 만져보고 있습니다. 개념자체가 개발자에게 기존에 익숙한 RDBMS와는 너무 달라서 튜토리얼 보고 단순한 사용정도는 할 수 있겠지만 관련해서 고민해 보려면 NoSQL에 대해서 좀 자세히 알아야 할 필요가 있게 느껴졌습니다. 사실 NoSQL에 대한 지식이 많다보니 고민 자체가 해결책이나 진도나 나가지 않고 계속 빙글빙글 도는 느낌이라 여기저기 자료를 좀 찾아서 정리해 보았습니다.





CAP Theorem
NoSQL에 대해서 이해하려면 먼저 CAP 이론에 대해서 알 필요가 있습니다. CAP이론은 Brewer's CAP Theorem   으로 알려져 있는데 분산 컴퓨팅 시스템에서 보장해야 하는 특징으로 아래 3가지를 정의하고 있습니다.

  • Consistency (일관성) : 모든 노드들은 동시에 같은 데이터를 보아야 합니다.
  • Availability (유효성) : 모든 노드는 항상 읽기와 쓰기를 할 수 있어야 합니다.
  • Partition Tolerance (파티션 허용차) : 시스템은 물리적인 네트워크 파티션을 넘어서도 잘 동작하여야 합니다

CAP 이론에 따르면 위 3가지 중에 동시에 2가지만 보장할수 있고 3개를 모두 보장하는 것이 불가능하다고 나와있습니다. 그래서 데이터를 관리할때 이 3가지 중에 어느 2가지에 중점을 두냐는 것은 아주 중요한 부분입니다. 이 부분을 이해하는데 Nathan Hurst   이 만든 아래의  Visual Guide to NoSQL Systems   는 큰 도움이 됩니다.

사용자 삽입 이미지

기존에 많이 사용하던 RDBMS는 3가지 중 CA에 집중하고 있습니다. 웹이 발전하면서 다양한 요구사항이 생겨나고 엄청난 양의 데이터를 처리해야 하게 되면서 RDBMS가 갖지 못한 P의 특성이 필요해졌고 그러면서 등장한 것이 NoSQL입니다. 좀더 풀어쓰면 데이터베이스에 대한 수평적 확장(Horizontal Scalability 즉 옆에 서버한대 더 배치해서 데이터베이스를 늘리고 싶다는 의미입니다.)에 대한 이슈가 발생했고 확장성이슈를 해결하기 위해서 P를 선택하다 보니 기존에 가지고 있던 C나 A의 특성중 하나를 포기해야 했습니다. 그래서 NoSQL에는 다양한 시도들이 있지만 가장 중요한 이슈는 확장성을 해결하려는 것으로 생각됩니다.

관계형 데이터베이스는 기본적으로 분산형을 고려해서 디자인 되지 않았습니다. 그래서 ACID(원자성, 일관성, 독립성, 지속성) 트랜잭션 같은 추상화와 고레벨 쿼리모델을 풍부하게 제공할 수 있지만 확장성이 좋지 못하기 때문에 모든 NoSQL 데이터베이스는 다양한 방법으로 확장성 이슈를 해결하기 위해 초점을 맞추고 있습니다. 각 NoSQL에는 여러가지 차이점들이 있지만 CAP의 범주에서만 보면 CP를 선택하거나 AP를 선택하게 됩니다.




왜 비관계형이어야 하는가?
NoSQL이 확장성 이슈를 해결하려고 CP나 AP의 특성을 선택했지만 구체적으로 어떤 특징을 선택하고 왜 그래야 했는지 이해할 필요가 있습니다. NoSQL은 많은 제품군들이 있는데 모두 같은 전략으로 접근하고 있지는 않고 각각에 제품에 따라 다양한 접근을 하고 있는데 아래 적힌 내용들은 비관계형으로 가기 위한 여러가지 특성들에 대한 이야기이고 제품군에 따라 아래의 특성들을 선택한 여부는 다른 것으로 보입니다.아래의 내용은 상당부분 VINEET GUPTA가 작성한 NoSql Databases - Part 1 - Landscape   를 참고하였습니다. 잘 정리된 문서라서 참고하시면 도움이 될 것입니다.



관계형 데이터 베이스는 확장하기가 어렵습니다.

Replication - 복제에 의한 확장
Master-Slave 구조에서는 결과를 슬레이브의 갯수만큼 복제해야 하는데 N개의 슬레이브에서 읽을 수 있기 때문에 Read는 빠르지만 Write에서는 병목현상이 발생하게 기 때문에 확장성에 대한 제한을 가지게 됩니다.
다중 마스터구조에서는 마스터를 추가함으로써 쓰기의 성능을 향상시킬 수 있는데 대신에 충돌이 발생할 가능성이 생기게 됩니다.

Partitioning(Sharding) - 분할에 의한 확장
Read만큼 Write도 확장할 수 있지만 애플리케이션레이어에서 파티션된 것을 인지하고 있어야 합니다.RDBMS의 가치는 관계에 있다고 할 수 있는데 파티션을 하면 이 관계가 깨져버리고 각 파티션된 조각간에 조인을 할 수 없기 때문에 관계에 대한 부분은 애플리케이션 레이어에서 책임져야 합니다. 일반적으로  RDBMS에서 수동  Sharding 은 쉽지 않습니다.



필요없는 특성들

UPDATE와 DELETE
Update와 Delete는 전통적으로 정보의 손실이 발생하기 때문에 잘 사용되지 않으며 후에 데이터 검사 및 재활성화를 위해서 기록해둘 필요가 있습니다. 그리고 사용자가 커뮤니티를 탈퇴한다고 그들의 글을 지우지 않듯이 도메인 관점에서는 실제로 삭제되지 않습니다.  이런 접근을 하게 되면 Update / Delete를 모두 Insert로 모델할수 있고 과거 데이터는 버전을 붙혀서 기록할 수 있으며 이 데이터들은 비활성데이터들이 됩니다. 이 INSET-only 시스템에서는 2개의 문제가 있는데 데이터베이스에서 종속(cascade)에 대한 트리거를 이용할 수 없으며 Query가 비활성 데이터를 걸러내야 할 필요가 있습니다.

JOIN
데이터가 많을 때 JOIN은 많은 양의 데이터에 복잡한 연산을 수행해야 하기 때문에 비용이 많이 들며 파티션을 넘어서는 동작되지 않기 때문에 피해야 합니다. 정규화는 일관된 데이터를 가지기 쉽게 하고 스토리지의 양을 줄이기 위해서 하는건데 반정규화(De-normalization)를 하면 JOIN문제를 피할 수 있습니다. 반정규화로 일관성에 대한 책임을 디비에서 애플리케이션으로 이동시킬수 있는데 이는 INSERT-only라면 어렵지 않습니다.

ACID 트랜젝션
Atomic (원자성) : 여러 레코드를 수정할 때 원자성은 필요없으며 단일키 원자성이면 충분합니다.
Consistency (일관성) : 대부분의 시스템은 C보다는 P나 A를 필요로 하기 때문에 엄격한 일관성을 가질 필요는 없고 대신 결과의 일관성(Eventually Consistent   )을 가질 수 있습니다.
Isolation (격리성) : 읽기에 최선을 다하는(Read-Committe) 것 이상의 격리성은 필요하지 않으며 단일키 원자성이 더 쉽습니다.
Durability (지속성) : 각 노드가 실패했을때도 이용되기 위해서는 메모리가 데이터를 충분히 보관할 수 있을정도로 저렴해지는 시점까지는 지속성이 필요합니다.

고정된 스키마
RDBMS에서는 데이터를 사용하기 전에 스키마를 정의해야하고 Index등을 정의해야 하는데 현재의 웹환경에서는 빠르게 새로운 피쳐를 추가하고 이미 존재하는 피쳐를 조정하기 위해서는 스키마 수정이 필수적으로 요구됩니다. 하지만 컬럼의 추가/수정/삭제는 row에 lock을 걸고 index의 수정은 테이블에 락을 걸기 때문에 스키마 수정이 어렵습니다.



어떤 특성들은 갖지 않습니다.
계층화 데이터나 그래프를 모델하는 것은 어렵습니다. 또한 빠른 응답을 위해서 디스크를 피하고 메인 메모리에서 데이터를 제공하는 것이 바람직한데 대부분의 관계형 데이터베이스는 디스크기반이기 때문에 쿼리들이 디스크에서 수행됩니다.





기대하는 특성들
NoSQL이 바라는 환경은 서버들이 다른 용량들을 가지고 수업이 퍼져나가는 것으로 이를 노드라고 부릅니다. 

높은 확장성
점진적으로 노드를 추가할 수 있어야 하고 이는 파티셔닝을 통해서 가능합니다. 

높은 Availability
실패의 단일포인트가 없으며 데이터는 복제되기 때문에 어떤 노드가 죽었을때도 데이터는 이용이 가능합니다.

높은 성능
디스크대신 메모리 기반으로 결과는 빠르게 리턴되어야 하며 이는 논블락킹 Write와 낮은 복잡성을 가진 알고리즘을 통해서 이룰수 있습니다.

원자성
각각의 쓰기는 원자성을 가질 필요가 있다.

일관성
강한 일관정은 필요없고 결과적인 일관성만 가지면 된다.(Read-Your-Writes1 일관성)

지속성
데이터는 휘말성 메모리만이 아닌 디스크에서 유지되어야 합니다.

배포의 유연함(Flexibility)
노드의 추가/삭제는 데이터를 분산하고 수동으로 중재할 필요없이 자동적으로 로드되어야 하며 분산 파일 시스템이나 공유스토리지 요구같은 제약이나 특수한 하드웨어같은 것이 필요없어야 합니다. 이기종간의 하드웨어에서 동작가능해야 합니다.

모델링의 유연함(Flexibility)
Key-Value쌍, 계층형 데이터, 그래프등 여러가지 타입의 데이터를 간단하게 모델할 수 있어야 합니다.

쿼리의 유연함(Flexibility)
하나의 호출에서 제공된 키에 대한 값이 묶음을 얻는 다중 GET과 키의 특정 범위에 기반한 데이터를 얻는 범위 쿼리가 필요합니다.

출처 : 
http://blog.outsider.ne.kr/519 
SELECT A.*
FROM A LEFT OUTER JOIN B
ON A.ID=B.ID
WHERE B.ID IS NULL

'Oracle/Mysql/Sql' 카테고리의 다른 글

Group by 알파벳 순으로 정렬 후 최종 1개만  (0) 2011.10.06
CAP Theorem  (0) 2011.06.28
계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
GRANT  (0) 2010.08.27
오라클를 이용한 계층구조

계층구조- SYS_CONNECT_BY_PATH 함수 db 

2006/03/28 14:59

http://blog.naver.com/peterppan/50002894715

계층구조를 가지는 테이블에서 Navigation Path 를 만들기 위하여
SYS_CONNECT_BY_PATH 함수를 사용할 수 있습니다.

순방향으로 전개할 때에는 이 path 가 root 에서 leaf 쪽으로 계층적으로
구성되어 반환되므로 상관이 없습니다.

예1) 순방향 전개시

SELECT EMPNO, LPAD(' ', 2*LEVEL-1)||SYS_CONNECT_BY_PATH(ENAME,'/') PATH
  FROM EMP
 START WITH JOB='PRESIDENT'
CONNECT BY PRIOR EMPNO = MGR

EMPNO    PATH
-----    ------------------------------
7839     /KING
7566       /KING/JONES
7788         /KING/JONES/SCOTT
7876           /KING/JONES/SCOTT/ADAMS
7902         /KING/JONES/FORD
7369           /KING/JONES/FORD/SMITH
7698       /KING/BLAKE
7499         /KING/BLAKE/ALLEN
7521         /KING/BLAKE/WARD
7654         /KING/BLAKE/MARTIN
7844         /KING/BLAKE/TURNER
7900         /KING/BLAKE/JAMES
7782       /KING/CLARK
7934         /KING/CLARK/MILLER

역방향으로 전개할 때에는 이 path가 leaf 에서 root 쪽으로 구성됩니다.
더 정확하게 말하자면 start with 절에 해당하는 node 의 level 이 1부터 시작하여
순방향이던 역방향이던 전개하면서 level 이 1씩 증가므로 level 순으로
path를 만들어 내는 것입니다.

예2) 역방향 전개

SELECT EMPNO, LPAD(' ', 2*LEVEL-1)||SYS_CONNECT_BY_PATH(ENAME,'/') PATH
  FROM EMP
 START WITH EMPNO = 7876
CONNECT BY  EMPNO = PRIOR MGR

EMPNO    PATH
-----    ------------------------------
7876     /ADAMS
7788       /ADAMS/SCOTT
7566         /ADAMS/SCOTT/JONES
7839           /ADAMS/SCOTT/JONES/KING

따라서 역방향으로 전개할 때에는 path가 거꾸로 나오므로
개발자들은 다음과 같이 2번에 걸친 전개를 하여 값을 구하곤 합니다.
1) 역방향 전개로 원하는 결과집합 생성하여 inline view로 묶고
2) 해당 집합에서 순방향 전개를 하여 sys_connect_by_path 함수로 올바른 path 생성

위의 제약사항을 reverse 함수를 2번 사용하는 것으로 해결해 보았습니다.

*********************************************************************************
* 주의 : reverse 함수는 내부적으로만 사용되는 undocumented 함수입니다.
*        support 되지 않으므로 사용에 대한 책임은 전적으로 사용자에게 있습니다.
*********************************************************************************

reverse 함수는 byte 단위로 앞뒤를 변경하므로 character 값들만 변경의 의미가 있습니다.

예3) reverse 함수 예제

SQL> select reverse('123'), reverse('한글'), reverse(sysdate), reverse(12) from dual;

REV REVE REVERSE(S REVERSE(12)
--- ---- --------- -----------
321 旁饑 14-AUG-50  -(.000E+98

하지만 reverse를 한번 더 적용하면 ~(~T) = T 와 같이 원래 값으로 변경됩니다.

예4) reverse 함수 2번 적용 예제

SQL> select reverse(reverse('123')), reverse(reverse('한글')), reverse(reverse(sysdate)), reverse(reverse(12)) from dual;

REV REVE REVERSE(R REVERSE(REVERSE(12))
--- ---- --------- --------------------
123 한글 11-AUG-05                   12

따라서 reverse를 먼저 적용하여 path를 만들고 전체적으로 한번 더 뒤집은 후 '/' 등의 
delimeter 처리만 약간 해주면 우리가 원하는 path를 만들어 낼 수 있습니다.

예5) 역방향 전개시 reverse 1회 적용

SELECT EMPNO, 
       SYS_CONNECT_BY_PATH(REVERSE(ENAME),'/') PATH
  FROM EMP
 START WITH EMPNO = 7876
CONNECT BY  EMPNO = PRIOR MGR

EMPNO    PATH
-----    ------------------------------
7876    /SMADA
7788    /SMADA/TTOCS
7566    /SMADA/TTOCS/SENOJ
7839    /SMADA/TTOCS/SENOJ/GNIK

예6) 역방향 전개 및 reverse 2회 적용

SELECT EMPNO, 
       LPAD(' ', 2*LEVEL-1)||'/'||
       RTRIM(REVERSE(SYS_CONNECT_BY_PATH(REVERSE(ENAME),'/')),'/') PATH
  FROM EMP
 START WITH EMPNO = 7876
CONNECT BY  EMPNO = PRIOR MGR

EMPNO    PATH
-----    ------------------------------
7876     /ADAMS
7788       /SCOTT/ADAMS
7566         /JONES/SCOTT/ADAMS
7839           /KING/JONES/SCOTT/ADAMS

 

============================================

 

EX) SELECT MENU_ID, SEQ, PRT_MENU_ID,
LEVEL, LPAD(' ', LEVEL*7) || MENU_NM, SYS_CONNECT_BY_PATH(MENU_NM, '')
FROM TABLE

CONNECT BY PRIOR MENU_ID = PRT_MENU_ID
START WITH PRT_MENU_ID = ''
ORDER SIBLINGS BY SEQ
 
ORDER SIBLINGS BY 컬럼  <-- CONNECT BY에서 정렬을 시켜준다.
 
SYS_CONNECT_BY_PATH(MENU_NM, '') <--  상위메뉴에서 부터 구분자가 인 값을 가져올수 있다.
 
메뉴1
메뉴1하위1
메뉴1하위2
이런식으로 나올수 있다.

'Oracle/Mysql/Sql' 카테고리의 다른 글

CAP Theorem  (0) 2011.06.28
두테이블을 비교해서 같지않은 값만 출력하기  (0) 2011.05.23
Mysql Table 메모리화  (0) 2011.03.15
GRANT  (0) 2010.08.27
hr계정 Lock풀기  (0) 2010.08.27

1. 테이블을 메모리화 시킨후 

2. 해당 DB의 Heap 사이즈도 변경시킨다.

3. Heap사이즈 변경 후

4. 해당 테이블에도 적용시킨다 .



select @@max_heap_table_size;    //사이즈 확인

set @@max_heap_table_size=536870912;  //512MB로 수정

SHOW TABLE STATUS LIKE '테이블 명'   //현재 테이블의 상태 확인 

ALTER TABLE '테이블명'ENGINE MEMORY  //수정한 메모리 적용


참고: http://ronaldbradford.com/blog/the-size-of-memory-tables-2008-12-12/ 
        http://dicortazar.wordpress.com/2010/07/09/changing-your-max_heap_table_size-variable/ 
        http://variable.jp/?tag=global-max_heap_table_size  

'Oracle/Mysql/Sql' 카테고리의 다른 글

두테이블을 비교해서 같지않은 값만 출력하기  (0) 2011.05.23
계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
GRANT  (0) 2010.08.27
hr계정 Lock풀기  (0) 2010.08.27
DataBase 파일들의 위치보기  (0) 2010.08.27

GRANT SELECT ON departments
TO candy 
Candy에게만 권한을 준다.

GRANT SELECT ON departments
TO candy WITH GRANT OPTION
해당권한을 candy 다른계정에게 줄수있다
Rovoke candy가 준 다른계정까지 같이 자동 삭제된다.

GRANT CREATE SESSION 
TO candy WITH ADMIN OPTION
해당권한을 candy 다른계정에게 줄수있다
Rovoke 하더라도 candy만 삭제되며 다른계정들은 영향을 받지 않는데 (주의해서 권한을주어야함)

'Oracle/Mysql/Sql' 카테고리의 다른 글

계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
hr계정 Lock풀기  (0) 2010.08.27
DataBase 파일들의 위치보기  (0) 2010.08.27
Sequences NextVal과 Currval  (0) 2010.08.27
Conn /as sysdba
nAlter user hr
nIdentifiedby oracle nAccount unlock

'Oracle/Mysql/Sql' 카테고리의 다른 글

계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
GRANT  (0) 2010.08.27
DataBase 파일들의 위치보기  (0) 2010.08.27
Sequences NextVal과 Currval  (0) 2010.08.27

SQL> --파일 위치 확인(DATABASE구성파일들의 위치)
SQL> --1. Datafile
SQL> select file_name from dba_data_files;

FILE_NAME
-----------------------------------------------------------------
C:\ORACLE\ORADATA\GILNET\SYSTEM01.DBF
C:\ORACLE\ORADATA\GILNET\UNDOTBS01.DBF
C:\ORACLE\ORADATA\GILNET\CWMLITE01.DBF
C:\ORACLE\ORADATA\GILNET\DRSYS01.DBF
C:\ORACLE\ORADATA\GILNET\EXAMPLE01.DBF
C:\ORACLE\ORADATA\GILNET\INDX01.DBF
C:\ORACLE\ORADATA\GILNET\ODM01.DBF
C:\ORACLE\ORADATA\GILNET\TOOLS01.DBF
C:\ORACLE\ORADATA\GILNET\USERS01.DBF
C:\ORACLE\ORADATA\GILNET\XDB01.DBF
C:\ORACLE\ORADATA\GILNET\PRACT01.DBF

11 개의 행이 선택되었습니다.

SQL> --2. Tempfile
SQL> select file_name from dba_temp_files;

FILE_NAME
-----------------------------------------------------------------
C:\ORACLE\ORADATA\GILNET\TEMP01.DBF

SQL> --3. Control 파일
SQL> select name from v$controlfile;

NAME
-----------------------------------------------------------------
C:\ORACLE\ORADATA\GILNET\CONTROL01.CTL
C:\ORACLE\ORADATA\GILNET\CONTROL02.CTL
C:\ORACLE\ORADATA\GILNET\CONTROL03.CTL

SQL> --4. REDO LOGFILE
SQL> select member from v$logfile;

MEMBER
-----------------------------------------------------------------
C:\ORACLE\ORADATA\GILNET\REDO03.LOG
C:\ORACLE\ORADATA\GILNET\REDO02.LOG
C:\ORACLE\ORADATA\GILNET\REDO01.LOG

SQL>

'Oracle/Mysql/Sql' 카테고리의 다른 글

계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
GRANT  (0) 2010.08.27
hr계정 Lock풀기  (0) 2010.08.27
Sequences NextVal과 Currval  (0) 2010.08.27



 

       

 

Sequence 는 자동으로 증가 하기때문에 학번등에는 잘사용이 안된다.
Memoery Cache사용 할경우 안 한경우보다 성능면 에서는 뛰어나다. 하지만 갑자기 정전 및 Oracle이 멈춘 다시 시작 할경우 Memoery에 올라간 그 이후 값부터 시작(Gap이생긴다)
 
 
 
Sequence 예제

SQL> create sequence empas_seq
    start with 1
    increment by 1
    maxvalue 1000000000;
Sequence created.
 
SQL> select empas_seq.currval from dual ;
select empas_seq.currval from dual
       *
ERROR at line 1:
ORA-08002: sequence EMPAS_SEQ.CURRVAL is not yet defined in this session
 
Error:  ORA 8002 
Text:   <name>.CURRVAL is not yet defined in this session 
-------------------------------------------------------------------------------
Cause:  Sequence CURRVAL was selected before sequence NEXTVAL was referenced.
Action: Select NEXTVAL from the sequence before selecting CURRVAL.
    
SQL> select empas_seq.nextval from dual ;
   NEXTVAL
----------
         1
SQL> select empas_seq.currval from dual ;
   CURRVAL
----------
         1
         
         
SQL>alter sequence empas_seq
    increment by 2
    nocycle
    maxvalue 10000
    minvalue 0 ;
Sequence altered.
 
If you omit both CACHE and NOCACHE, Oracle caches 20 sequence numbers by default. 
 
SQL> select SEQUENCE_NAME, MIN_VALUE, MAX_VALUE, INCREMENT_BY,          
        CYCLE_FLAG, CACHE_SIZE, LAST_NUMBER from user_sequences ;
SEQUENCE_NAME      MIN_VALUE  MAX_VALUE INCREMENT_BY C CACHE_SIZE LAST_NUMBER
----------------- ---------- ---------- ------------ - ---------- -----------
EMPAS_SEQ             0      10000            2      N         20   3
SQL> conn / as sysdba
Connected.
 
Sequence 를 shared pool 에 고정 하기
SQL> execute dbms_shared_pool.keep('SCOTT.EMPAS_SEQ','Q') ;
PL/SQL procedure successfully completed.
 
Sequence 를 shared pool 에 고정 해제 하기
SQL> execute dbms_shared_pool.unkeep('SCOTT.EMPAS_SEQ','Q') ;
PL/SQL procedure successfully completed.

관련 문서
No. 11446
CACHING ORACLE SEQUENCES
========================

  오라클 sequence 를 CACHE option 을 enabled 시키고 사용하는 application 에서
가끔 몇몇 값들의 번호가 skip 된것을 볼 수 있다. 이제 왜 sequence 번호가
skipped 되고 그 현상을 최소화할 수 있는 방법은 무엇인지 알아보자.
  
Non-CACHE and CACHE Mode
  non-cache 모드를 사용할 때에는 'nextval' 을 요청하는 sequence 의 현재값은
'increment' 로 지정된 값만큼 증가되는 새로운 값을 얻을 수 있다. 예를들어
현재값이 '0', increment 값이 '1', 그리고 no cache 라면 현재값은 '1' 이 될
것이다. 
  그러나, cache 모드를 사용한다면 'nextval' 을 요청한 sequence 의 현재값은
increment 값과 cache 의 배수만큼 증가된 값을 얻게된다. 그리고, 다음번 nextval
가 호출될때는 반드시 cached sequence 값이 사용되며 이들 중 이전 값보다
increment 값만큼 증가된 sequence 값을 return 한다. 다시 말해 마지막에 도달할
때까지 번호는 cache 에서 return 된다. cache 값이 5 이고, increment 값이 1 인
다음의 표를 살펴보자.
         Number Returned     Sequence Current      Cache Current
*start*       *none*               0                   *none*
1st access      1                  5                      1
2nd access      2                  5                      2
3rd access      3                  5                      3
4th access      4                  5                      4
5th access      5                  5                      5
6th access      6                 10                      6
7th access      7                 10                      7
만약, cache 가 절대 손실되지 않는다고 가정한다면 cached sequence 값은 항상
non-cached 그것과 같을 것이다. 그러나, sequence cache 는 다른 cache 정보와
마찮가지로 shared pool 에 보관되어지기 때문에 충분히 자주 사용되어지지 않는다면
shared pool 로부터 aged out 되어질 수 있다. 또, instance shutdown 의 경우에도
cache 값을 잃게 된다. 위의 두 경우 특히, 두번째의 경우 때문에 application 에서
skip 되어지지 않는 sequence 를 사용해야 하는 상황이라면 반드시 non-cached
sequence 를 사용해야 한다.
  위의 표는 데이터베이스의 shutdown 이 발생할 경우 다음처럼 반복될 수 있다.

         Number Returned     Sequence Current      Cache Current
*start*      *none*               0                   *none*
1st access     1                  5                      1
2nd access     2                  5                      2
                  *cache aged out* 
3rd access     5                 10                      5
4th access     6                 10                      6
                  *shutdown*
5th access    10                 15                     10
6th access    11                 15                     11
7th access    12                 15                     12
  이러한 aging problem 을 처리하기 위해서 shared pool 에 sequences 을
PIN'd 시켜주는 DBMS_SHARED_POOL.KEEP 프로시져가 있다. 이는 물론 shutdown
의 경우에는 cache 를 보호할 수 없겠지만 sequence 값들이 aged out 되어
skipped 되는 것을 어느정도 피할 수는 있다. 그러나, sequence 가 자주
사용되어지지 않는 경우라면 이는 반드시 PIN'd 되어야 하는데 이러한 경우
sequence 를 cache 함으로 얻을 수 있는 장점은 없는 셈이다.
  sequence 를 caching 한다는 것은 오라클이 sequence 의 다음값을 얻으려 할때
disk 를 access 하는 대신에 shared pool 즉 memory 의 한부분을 바로 이용하므로
성능향상을 꾀할 수 있다는 것이다. 따라서, sequences 가 빈번히 사용되는 경우라면
시간을 절약할 수 있겠지만 그렇지 않은 경우라면 차라리 cache 를 disabled 시키는
것이 낫다고 할 수 있다.
  오라클 7.2 이하 버전에서는 sequence cache 가 rowcache(dictionary cache)
에 보관되어졌지만 7.3 이후 버전에서는 sequence cache 가 library cache 에
보관된다. 그래서, 7.3 이나 8.x 에서는 sequence cache 는 보다 쉽게 aged out
될 수 있다. 따라서, 필요한 경우 DBMS_SHARED_POOL.KEEP 프로시져를 사용할 수
있다. 예를 들어 sequence 이름이 'SEQ' 인 경우 
dbms_shared_pool.keep('seq', 'q') 로 해당 sequence 를 shared_pool 에
PIN'd 시킬 수 있다.
 
 
Any reference to CURRVAL always returns the sequence's current value, which is the value returned by the last reference to NEXTVAL.
 
Note that before you use CURRVAL for a sequence in your session, you must first initialize the sequence with NEXTVAL.
 
Within a single SQL statement containing a reference to NEXTVAL, Oracle increments the sequence only once:
 
A sequence can be accessed by many users concurrently with no waiting or locking.
 
!! Sequence 와 Table 은 아무런 관계가 없다..
[ 많은 분들이 오해가 있는듯... table 에 sequence 가 엮인것으로... ]
관계를 맺는것은 App 단에서 하는것이다.
[ 즉 호출해서 해당 테이블에 row insert 시에 sequence 를 호출해서 쓰면 된다.]
 
 App에서 Sequence 를 사용시에 Nextval 을 하는 것은
1. sesesion 을 맺은 후 currval 을 사용하기 위해서는 우선 먼저 nextval 을 사용함으로
   sequence 를 초기화 해야 하기때문에.
2. sequecne 가 증가 하는 조건은 nextval 조회시 이다..
    duplicate 발생할 여기가 있는듯....
결론적으로 app에서는 nextval 을 가져다 쓰면 된다.!!!
 
 
!! 권한 분리 환경 이라면 [ Object Owner 와 DML User 의 분리 ]
즉 Sequence Onwer 와 Sequecne 를 사용하는 [ App User] 가 다른 환경 이라면
App User 를 위해서 아래와 같이 추가 작업을 한다.
create public synonym  empas_seq for empas_seq ;
grant select on empas_seq to app_user ;

'Oracle/Mysql/Sql' 카테고리의 다른 글

계층구조- SYS_CONNECT_BY_PATH 함수  (0) 2011.04.06
Mysql Table 메모리화  (0) 2011.03.15
GRANT  (0) 2010.08.27
hr계정 Lock풀기  (0) 2010.08.27
DataBase 파일들의 위치보기  (0) 2010.08.27

+ Recent posts