안녕하세요 초보sqler입니다...
mssql 사용중이며 현재 테이블에
seq, maincd(pk), 기타 컬럼들이 있습니다.
seq는 SET @tmpSeq = (SELECT ISNULL(MAX(Seq+1),1) FROM table)
이런식으로 해서 고유한 값을 가지게 해놨습니다.
seq는 해당 데이터가 수정될 경우에 조건절에 걸기 위해서 만들었습니다.
화면에서 디비로 넘어갈때 현재 화면에 보여지는 값들이 넘어가기 때문에
(seq, 다른 변수들은 화면에 뿌려주지 않으면 기존값을 넘길 수 있습니다.)
바뀐 maincd밖에 안넘어가는 구조입니다..
그런데 이렇게 만든 테이블을 보시고 다른분1께서
maincd를 가지고 수정을 하면 되지 굳이 seq를 만들어서 넘길 필요가 없지않느냐고 하셧는데
1. 그러면 조건절에 안걸리기때문에 도저히 수정을 할 수가 없지 않나요??
제생각에 seq없이 수정을 하려면 디비로 넘길때 임시변수에 기존 maincd값을 넣고 그걸로 조건절에 넣는 방법뿐인것 같은데
2. 혹시 다른방법이 있는지?
3. 없다면 제가 설계한 seq를 가지고 하는것과 임시변수를 가지고 하는것 중 무엇이 일반적이며 더 효과가 좋은지?
그리고 같은분께서
maincd뿐만 아니라 seq를 같이 pk를 하던지
seq를 pk로 주고 maincd는 unique속성을 주라고 하시는데
4. 기존에 설계한 것과 큰 차이를 못느끼겟는데 왜 저렇게 바꾸라고 하는지 이해가 가질 않아서 문의드립니다.
다른분1말고 나머지분들은 다른분1이 잘 몰라서 그러는거라고 하시는데
뭐가 맞는말인지 알고싶습니다...
글이 좀 긴데 4개 질문에 답변 좀 부탁드리겟습니다~
Comment 15
-
처리짱
2013.09.26 16:45
-
하하하하하
2013.09.26 16:49
제 글을 보시면 화면상에 있는 값만 넘어 간다고 말씀드렸습니다..
예를들어
a = 2라고 되어있는 것을
a = 3으로 바꿀시에
값이 넘어가는것은 3만 넘어가게 됩니다.
기존에 있던 2라는 값은 못넘기는 구조입니다.
-
군고구마
2013.09.26 16:49
1. 그러면 조건절에 안걸리기때문에 도저히 수정을 할 수가 없지 않나요??
maincd는 PK라고 명시해 주셨는데요. PK가 모두 고유한 키라고 생각하시는 분이 있지만 아닌 경우도 있습니다.
클러스터 인덱스의 경우 기본적으로 고유한 속성이기떄문에 seq대신에 써도 상관없을 듯 합니다.
왜냐면 seq로 수정하는 이유는 그값이 그 테이블에서 유일한 값이라서 라고 생각하는데
maincd 도 PK라면 그 테이블에서 고유할 것입니다. 그럼 이것을 where조건에 걸고 수정해도 무방하다고 생각합니다.
2. 혹시 다른방법이 있는지?
SET @maincd = CAST(SCOPE_IDENTITY() AS INT) 를 사용해 보시기 바랍니다.
SCOPE_IDENTITY()를 도움말 검색하면 많은 정보를 볼수 있을 것 입니다.
그후에 넘겨야 하는 테이블에 @seq대신에 @maincd 를 넣으면 됩니다.
3. 없다면 제가 설계한 seq를 가지고 하는것과 임시변수를 가지고 하는것 중 무엇이 일반적이며 더 효과가 좋은지?
3번 질문은 답변이 필요없는것 같습니다.
4. 기존에 설계한 것과 큰 차이를 못느끼겟는데 왜 저렇게 바꾸라고 하는지
seq에 만약에 인덱스가 걸려있지 않을 경우 성능에 엄청난 저하를 불러올 수 있습니다.
우선 seq번호를 기준으로 정렬이 되지 않고 PK인 maincd를 기준으로 정렬하며 인덱스가 없는 경우 성능 차이는
당연히 아실거라고 생각합니다.
-
군고구마
2013.09.26 16:50
추가적으로 seq는 지우고 maincd를 위의 2번 방법을 사용하는것을 권해 드립니다.
-
하하하하하
2013.09.26 16:55
maincd를 조건절에 넣으면
기존에
seq
maincd
etc
1
aa
3
bb
이런 테이블이 화면에서 뿌려지는데
2번째행의 bb의 값을 cc로 바꾸고 싶어서
seq
maincd
etc
1
aa
3
cc
이렇게 수정한 다음 화면에서 버튼을 눌렀을때 넘어가는것은
1,aa
3,cc
이렇게 4개의 값만 넘어갑니다
이런경우인데도 maincd를 조건절에 넣어서 수정할 수 잇나요?
제 짧은 지식으로는..
update table
set maincd = '33'
where maincd = '22'
이렇게 해야하는데 저 sp를 날릴 때에 22라는 값은 넘기지 못하는 구조입니다.
-
군고구마
2013.09.26 16:59
PK를 변형하는 것은 저의 개인적인 생각으로는 좋지 않은 것 같습니다만...
만약에 바꿔야 한다면 어쩔수 없이 seq를 사용해야 합니다.
대신 seq를 클러스터 인덱스로 잡고 maincd를 넌클러스터로 잡는게 좀 더 좋은 방법 일듯 싶습니다.
maincd의 경우 수정이 빈번하게 일어날 것으로 보이는데
지금 위에 보시면 처음 화면과 두번쨰 화면에서 maincd의 값이 바뀌므로 어쩔수 없이 seq로 밖에
수정이 안될 듯 싶습니다.
-
하하하하하
2013.09.26 17:08
아 그럼 pk값을 seq로 변경 하고 maincd는 다른분말씀대로 unique 속성을 주는게 가장 좋은 것 같습니다.
저와 다른분1을 제외한 분들이 이해가 안갔던부분은
maincd 컬럼만 가지고 어떻게 수정을 할수 있는지 였습니다..
해당 문제는 해결이 된것 같습니다.
-
처리짱
2013.09.26 17:11
음.. 절대 태클은 아니고요...
primary key = 고유키로 아는데. 아닌 경우가 어떤 경우 인가요?
-
맨즈밤
2013.09.26 17:39
제가 대신 추리해보건데,, 클러스터드인덱스 잡을때 유니크속성을 지정하지않으면 내부적으로 4바이트 식별자컬럼이 추가되는걸 말하신게 아닐까요
-
맨즈밤
2013.09.26 16:50
제가 모델링쪽은 부족함이 많지만 왠지 님께서 말씀하신 "다른분1" 에 의견에 가까워서 끄적여보고자 합니다.
maincd 의 값이 바뀌나요? . 그래서 where 절에 seq 걸고 update ~ set maincd=@maincd 이렇게 하는가보네요. PK는 바뀌는값을 지정하지 않아야 합니다. 문법적으로 오류는 없지만 성능상 불이익이 따릅니다. 특히나 넌클러스터드 인덱스가 주렁주렁 달린경우는요.
그리고 성능을 떠나서 해당 로우를 유일하게 식별하고자 하는 컬럼이 바뀐다면 그건 이미 식별자라고 할수없지요. "AAA" 라는 코드가 어제는 초코파이였다가 오늘은 오예스였다가 내일은 ?
만약 해당 테이블의 자식테이블이 있을때 자식테이블도 모두 바꿔줘야 하는 경우가생기지 않을까요?
가령 AAA 코드가 초코파이로 상품테이블로 등록된 상태에서 매출이 초코파이 3개 팔리면 곧 매출테이블에 AAA코드로 판매량 3개로 등록이 될텐데요. 다음날 AAA 코드는 오예스로 바꾸고 BBB 코드를 초코파이로 바꾸면 매출테이블에서 AAA로 된걸 모두 BBB로
바꾸어야 하는경우가 생기지않을까요?
지금 봐서는 오히려SEQ가 PK 식별자의 의미에 가깝다고 볼수있을듯하네요. maincd 는 그냥 유니크속성의 인덱스컬럼정도
-
하하하하하
2013.09.26 17:02
아... pk를 바뀌지않는 값으로 넣어야 하는게 성능상 좋기 때문에
바뀌지 않는 seq를 pk로 주고 maincd는 unique속성으로 주라는 말씀이시네요?
말씀하신 것처럼 하위 테이블이 있어서 기본키가 바뀌면 해당 자식 테이블에있는 값들이 외래키로 되어있어서 자동으로 변경되게끔 했습니다.
그래서 maincd를 기본키로 줬던것인데 잘못생각한것 같습니다..
-
건우아빠
2013.09.26 16:59
개발툴이 ?
하고 싶으신대로 하셔도 됩니다..
seq, maincd 의 목적이 일부 상충되는 부분이 있어서 굳이 seq를 쓰지 않으셔도 될듯 하기는 하지만 ..
seq는 자동 증가 값이라면 identity 설정도 가능 하구요...
다른분1말고 나머지분들은 다른분1이 잘 몰라서 그러는거라고 하시는데 --> 반대 일수도 있습니다. ㅎㅎ
디비를 이용해서 어플을 개발 하시는데 어플에서 처리 방법(스킬)에 따라 설계가 달라 질수 있습니다.
물론 디비의 종류에 따라 설계 방법이 달라 질수도 있구요.
일단 두 컬럼의 목적이 뭔가를 생각해 보시면 답은 스스로 찾을수 있을듯 합니다.
-
하하하하하
2013.09.26 17:10
안녕하세요
작년에도 답변을 달아주셨던 기억이 있는데 오랜만에 뵙는것 같습니다^^;;;
잘몰라서 그러는것 같다 이말은
'maincd만 가지고 수정을 하는것'에 한해서 말씀하신거였습니다..ㅋ
아 개발툴은 visual studio랑 ssms 사용하고있습니다~
많은 분들 답변이 많이 도움이 된것 같습니다^^
-
하하하하하
2013.09.26 17:33
그리고 seq에identity를 걸지 않고 저렇게 한 이유는..
identity로 걸 경우에
seq가 1 2 3 4가 있다가 4가 지워지면 그다음 seq는 4가 되고싶은데 identity로 설정하면 5가 되기때문에
저렇게 했습니다.. 꼭 4가 되어야 하는 것은 아니지만.. 그냥 5가 아닌 4가 되게끔 하고 싶어서.....ㅋ
-
건우아빠
2013.09.26 18:31
재 짧은 견해로는요..
1. maincd가 PK인데 왜 조건절에 안걸리는지요? ;;
2. seq를 굳이 쓰셔야 겠다면 IDENTITY 속성을 주시면 되겟죠?
데이터가 많아지면은 MAX할떄 무지느려지니 인덱스를 하나 거는게 좋겟죠.
3. 임시변수가 어떤걸 말씀하시는지.. 필요 없는 컬럼은 굳이 안만드는게 좋겠죠.. 사이즈가 줄어드니..
4. maincd가 PK인데 seq는 필요 없을거 같은데요..?