pk 순차증가 방법에 대해 여쭤보고 싶습니다. 0 7 4,835

by 구기웅 [SQL Query] 데이터트랜젝션 [2014.12.10 18:02:30]


다름이 아니라 insert 진행시에 seq를 max +1을 통해서 증가 시키고 있습니다.

select nvl(max(seq), 0) +1 from dual  이런식으로요

해당부분에서 문제가 될수 있나요 ? 

db서버는 1개고 was는 2개 있습니다. 

재수가 없어서 사용자가 동시 쿼리를 때려도 오라클내에서 insert문을 치고 빠져나올경우 0.00 초때의 오차범위를 가지고 있다고 할경우에 seq가 pk 인대 2개가 insert가 때려질수 있나요?

또는 해당부분이 문제가 될 경우에 대해서 자세한 설명 부탁드릴수 있을까요? 

db에 대해서 모르는게 많고 아직 경험도 없는 개발자라 쓸대없는 개념없는 질문일수도 있지만 여쭤봅니다.

10년차 이상된 선임분들은 혹시 재수가 없는경우를 드시면서 nextval을 쓰라고 하시는데 동일한 얘기 아닌가 생각되어 질문드려 봅니다. 

저의 경우는 저런식의 select 를 할경우 내부적으로 seq를 숫자 순차증가가 아닌 개별로도 만들수 있고 특별히 저쿼리에서 문제를 못느끼고 있습니다.

정말 데이터 구조에 대해서 박학하신분들의 도움이 필요해요 ㅠ감사합니다.

by 비주류 [2014.12.10 20:16:23]

1. seq 가 테이블 컬럼이지요? select nvl(max(seq), 0) +1 from dual(?) ...
1) unique 제약이 있다면 select 에서 중복값을 받아와도 insert 시 에러가 떨어질거구요. 이 경우 재처리하시면 될 것 같고 (pk 라 하셨으니 이 경우겠네요. 제약조건 있는데 중복 입력되지는 않습니다.)

2) unique 제약이 없다면 중복 입력이 될 수 있습니다. 아래 같은 시나리오가 있겠네요. WAS가 1개여도 보통 여러 thread, process가 생겨 처리하므로 동일합니다.
  A) SELECT
nvl(max(seq), 0) +1 ...
  B) SELECT nvl(max(seq), 0) +1 ...
  A) INSERT ...
  B) INSERT ...

2. 제약조건 + 에러 재처리를 고려하지 않고 반드시 유일한 순차 증가값이 필요하면 말씀하신 것처럼 sequence.nextval 을 쓰셔야 합니다. 성능도 더 나을거구요.


by lovekod2hj [2014.12.10 21:12:09]

위에서 설명 잘 해주셨네요.

일반적으로 insert, update, delete 가 commit 완료된 후에 nvl(max(seq), 0) +1를 해야지만 정확한데 경우에 따라 commit 되기전에 조회가 된다면 중복된 값이 생길 수 있는 여지(진짜 생기고 나중에 테스트 해보려고 하면 안 생기죠)는 있습니다.

다만 db종류에 따라 자동으로 값이 증가하는 것으 처리하는 방식이 다를 수는 있으니 확인은 필요합니다.


by 윈짱천사 [2014.12.11 11:28:48]

"CREATE SEQUENCE" 를 사용해 보세요..

"시퀀스명.nextval" 이렇게 사용하시면 될듯합니다.


by 비주류 [2014.12.11 12:56:40]

concepts 매뉴얼이나 기타 서적에서 관련 내용을 한번 보셔도 좋겠습니다.

http://docs.oracle.com/cd/E11882_01/server.112/e40540/consist.htm#CNCPT1313


by 구기웅 [2014.12.11 14:57:31]

고수님들 정보 대단히 감사합니다.

결국은 seq의 컬럼은 pk로 지정을 했기 때문에 unique index가 될거고 해당부분은 중복을 허용하지 않기 때문에 비주류님 말씀처럼 insert insert처리 진행시에 같은 값을 가져왔기 때문에 에러가 떨어진다는 말씀으로 이해를 했습니다.

다른 사항에 대한것들은 unique key가 아닐경우에 고려해야 할부분이라고 생각하면 될까요?

결국 위의 가정에서 문제가 생겨도 error가 떨어지기 때문에 insert처리가 되지 않을거고 해당부분은 결국 먼저 insert된 글은 정상처리가 되며 후에 insert가 된 데이터는 에러가 생기는게 맞는거군요.

 

하나더 궁금한건 위의 비주류님 말씀대로 2번째 상황 unique가 아닌 경우에 대해서도 에러가 발생하지 않나요 ? 그렇다면 nextval이라고 하는 경우에서는 에러가 발생하지 않는다라는 말씀이신지요~

대부분 게시판에 게시글의 번호를 seq로 잡고 진행할경우에 다른분들은 nextval를 사용하고 계신가요?

이해에 도움주신 고수분들 감사합니다.


by lovekod2hj [2014.12.11 15:24:21]

pk, unique가 설정되어 있지 않다면 단순히 일반적인 데이터 컬럼이 되어 버립니다. 때문에 중복입력이 가능합니다.

그리고 일반적으로 sequence를 쓰는 경우는 순번이 의미는 있지만 연속적이지 않아도 되는 경우입니다. nextval로 사용한 값은 다시 사용할 수 없기 때문에 삭제 등이 있을 경우 순번이 연속적이지 않게 됩니다.


by 비주류 [2014.12.11 19:03:23]

말씀하신 에러가 중복입력(업무적인 이상)인지 DB 처리 에러인지는 모르겠으나,
insert시 에러는 값이 잘못됐을 때(데이터타입 차이, unique 제약조건 위반 등) 발생하겠고,
sequence.nextval 부분에서 에러가 난다고 보기는 어려울 것 같습니다.

 

결국, 중복값 입력을 막으려면,
unique 제약조건 지정이 확실하고, (업무적으로도 명세를 보고 유일한 값을 갖는지 알 수 있음)
초기화하지 않는한 sequence를 사용해도 유일값이 보장되고, (Oracle 내부에서 row cache lock을 이용한 동기화)
그외엔, 별도 동기화 처리를 적용하여, max+1 또는 채번 테이블을 사용하는 방법(atomic(?) 연산으로 만듦) 등이 가능하겠네요.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입