database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
ㆍMS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MS-SQL Q&A 1808 게시물 읽기
No. 1808
기본 키에 대한 개념 질문입니다.
작성자
이상도
작성일
2005-03-07 15:31
조회수
6,290

기본 키가 되는 열의 데이타는 중복되지 않는 유일한 것이여야 합니다.

그러나 테이블 생성시 유일한 값(예:item20050306 라는 고유품명 char값)이

있는데도 버릇처럼 저는 이것을 기본 키가되는 열로 사용하지 않고 기본 키가되는

열을 추가 합니다. 예를 들면 1씩증가하는... int 값으로..

이론적으로만 따진다면 int값이 char보다 적은 비교로 데이타를 찾을 수 있게에

버릇처럼 사용하는데요..

제 개념이 맞는것인지? 현업에서도 그렇게 설계하시는지?

 

p.s : 중소기없전산담당자인데 외주준 프로그램의 DB스키마를 보면 저런식으로

설계가 되어 있길레 제가 잘못이해하고 있는 것은 아닌지 해서입니다.

이 글에 대한 댓글이 총 10건 있습니다.

identity 로 기본키를 만드셔도 되구요.

고유한 데이터(상품제조번호) 등..으로 만드셔도 됩니다.

다만, 차후에 기본키가 되는것이 다른테이블에서 어떻게 쓰이는가와

데이터 건수에 따라서 속도가 달라질 수 있습니다.

 

당연히 속도를 위해서는 기본키를 짧게 쓰는것이 좋겠지요.

긴 char 기본키보다는 짧은 int형의 키가 적합하고 변경이 있어서는 절대 안되구요.

 

질의하신 내용에 대답이 되었는지요..

 

 

kkk님이 2005-03-07 19:43에 작성한 댓글입니다. Edit

감사합니다.

로또 당첨되세요...

이상도님이 2005-03-08 10:28에 작성한 댓글입니다. Edit

제가 아는 한도 내에서 말씀드리자면,

 

1. 유일한 primary key가 존재하는데도 identity int를 추가해서 사용하는 것은 불필요한 낭비입니다..

이유 1. identity int가 존재해야할 특별한 이유가 없다. 아마도 identity int를 가지고 검색한다던지 하는 경우는 없겠죠.. 그냥 추가한 거니까요..

이유 2. primary key로 할려던 키(원래 유일한 키)로 검색을 하기 위해서는 별도의 index를 잡아줘야 한다..

 

즉, 이유 1.에서 물론 primary key 인덱스는 int로 잡기 때문에 index자체크기는 적습니다만, 불필요한 index가 생기며, 불필요한 칼럼이기 때문에 좋지 않습니다.. 더군다나, primary key로 할려던 키에 대한 constraint가 전혀 걸리지 않구요.. 만약 별도의 unique constraint를 걸어주어야 한다면 그 역시 낭비가 됩니다..

 

개선방안, primary key로 할려던 키를 primary 키로 합니다..

만약, identity처럼 일정한 order를 가지는 값이 아니라면, non-clustered primary key로 잡아주시는게 좋습니다..

 

그리고, 당연한 얘기입니다만, unique한 primary key가 될 수 있는 후보키들이 많이 있다면, 역시 bytes가 적게 잡아먹는 column이 유리합니다..

 

그럼..

길가는 나그네..님이 2005-03-08 10:50에 작성한 댓글입니다. Edit

음.. 제가 글을 써 놓고 보니까..

 

미묘한 차이가 존재할 수 있을 것도 같습니다..

 

인덱스 구조를 저도 명확히 이해하고 있지 않아서여.. ^^;;

 

만약 non-clustered index가 address 값이 아닌 primary key 값을 주소값 대신에 가지고 있다면, identity int를 사용하는 것이 유리할 수 있을 것 같네요..

 

그런데, 아마도 제 추측입니다만 primary key가 address 값을 나타내는 데이터 크기보다 커져버리면, non-clustered index의 address값을 memory의 address를 그대로 가지지 않을까 싶네요.. 엄청 큰 primary key 값을 그대로 가지지 않고요..

수정 ==> primary key 대상 키 값이 어느 정도 큰 값이면 non-clustered primary key로 지정을 해 주시면 해결될 것 같습니다.. 그럼..

 

그럼.. 이건 어떻게 테스트해봐야 할 지 모르겠네요.. ^^;;

혹시 여리님은 아실려나 몰라요.. ^^*

 

길가는 나그네..님이 2005-03-08 11:05에 작성한 댓글입니다.
이 댓글은 2005-03-08 11:15에 마지막으로 수정되었습니다. Edit

습관적으로 identity를 pk로 잡는다 <- 이 부분에서는 굉장히 부정적입니다.

pk로 잡는 다는 것은 mssql에서는 이미 index를 가지므로 용량을 차지하게 됩니다.

기본적으로 설정하지 않으면 nonCluster로 설정이 되는게 기본입니다.

이쯤되니 서설 개념들이 나오기 시작하네요.

pk / clustered index / non-clustered index 등이 그것인데요.

일단 간단하게 개념은 집고 넘어가야 헷갈리지 않을 듯합니다.

 

pk는 정오보다 흔히들 주키라고 하며 프라이머리라고도 부릅니다.

이 키의 특성은 unique해야 하며(중복불허), Null이 허용되지 않습니다.

그리고 pk로 잡는거와 동시 index가 생성됩니다.

 

cluster와 noncluster의 대략적인 차이는 이 개념을 설명하는데도

아마도 굉장히 긴 개념이야기를 해야 하지 않을까 싶습니다.

그런데 간단히 말해 순차적이냐 아니면 범주형이냐에 따라

cluster와 noncluster를 사용한다고 보시면 됩니다.

(이건 저의 특징인지 모르겠지만... 예를 들어 identity라면 당연 cluster

남/여 이런 경우라면 noncluster 그러나 이건 권장정도이지 절대는 아닙니다. 여긴 안티를 걸지 마십시요.)

 

또한 인덱스는 그 사용빈도(검색에서의), 자료의 밀도에 의해

얼마나 검색의 효율을 꽤할 수 있느냐의 문제이므로 좀더 고민을 하여야 하지 않을까 싶습니다.

 

다만 그 identity 되고 있는 column이 사용빈도가 많으며

table상에 유일키가 되어 있다면 그렇게 설정되는 것이 많으나

대부분의 경우는 그게 불필요함에도 습관적으로 잡는 경우가 많았습니다.

 

따라서 저는 사용빈도가 많음에도 중복이 되고 있다면

여러키를 복합으로 하여 index를 잡는것이 더 효율적이지 않을까 하는

그런 추천을 해봅니다.

물론 이건 절대가 아니라 운영상의 query문에 대한 것을 본 다음 결정해야 하며

(어플리케이션에서 사용되거나 sp등에서 사용되는 것을 쭉 훑어야겠지만...)

그리고 더 나은 키를 만들거나 아니면 복합키로 잡는 방법을 생각해야 하며

마지막 데이터의 성격에 따라 이놈을 unique, cluster, noncluster로 만드는 것을 고려해야겠죠.

 

아참 그리고 복합키로 잡을때는 카디날러티도 고려에 넣어야 하는데

이건 손호성님의 deep inside Tsql을 추천할께요..

 

 

여리님이 2005-03-08 15:49에 작성한 댓글입니다. Edit

이 내용은 저도 확신할 수 없는 내용입니다..

 

1. create table => clustered index는 무조건 만들어집니다..

primary key를 잡고 안 잡고 상관없이, primary key를 잡지 않더라도 MSSQL 내부적으로 RID를 잡습니다.. 왜냐면 page의 data를 찾아가기 위해서 RID 정보를 가져야만 하기 때문이죠..

여기서 잡히는 RID는 clustered index가 됩니다.. 순차적인 주소를 나타내기 때문이지 않을까 여겨집니다만..

 

2. primary => clustered 의 경우와 non-clustered의 경우..

여기서 중요한 점은,

primary key 이외의 index가 있느냐 없느냐입니다.. 있다면, 과연 얼마나 있느냐가 되겠죠..

만약, primary key 이외의 index가 없다면, 복합키로 구성되는 제법 큰 primary key가 되더라도 특별히 문제가 없습니다.. 왜냐면, 여기서 생성되어진 primary key clustered가 다른 index의 정보로서 사용되어지지 않기 때문이죠..

즉, 다른 index가 있을 경우,

other index => primary key clustered => data 식으로 다른 index 정보에 primary key clustered가 들어가기 때문에 index로서 상당히 불리해집니다..

이런 경우에 primary key non-clustered를 잡아주게 되면,

other index => rid => data 식으로 data를 찾아가기 때문에 primary가 복합키로 구성되더라도 다른 index에 별 영향을 안 끼치게 됩니다..

 

3. int identity primary key를 사용하는 경우는 그럼 언제인가?

primary key가 될수 있는 unique column이 없을 경우에 identity column을 하나 추가 시켜 놓는 것은 좋을 것 같습니다.. primary key가 없는 테이블은 그냥 놔두기는 좀 그렇죠.. ^^;; 만약에 trigger등을 설정한다던가 하더라도 문제가 많을 겁니다..

어쨌던, indentity int는 순차적으로 증가하는 값이고, 다른 index에 포함되더라도 4bytes짜리니까 괜찮지 않을까 싶네요..

 

이상 제 생각입니다..

 

참고로 제가 테스트 해 본 결과 다음과 같은 사실을 알 수 있습니다..

column a primary key clustered

column b other index

이 경우 column b index seek를 이용하여 a, b를 select할 경우,

bookmark는 일어나지 않습니다만,

column a가 primary key nonclustered의 경우는 bookmark 작업이 발생합니다..

이것이 무엇을 의미하는지는 여러분들 각자 생각해 보시기 바랍니다..

 

그럼, 좋은 하루 되세여~~

길가는 나그네..님이 2005-03-08 16:59에 작성한 댓글입니다. Edit

좋네요. 저도 깊이 있게 생각해볼 시간은 없었고

create table 당시에 clustered index가 만들어짐은 처음이네요.

아님 알고 있었는데도 약한 기억력인지 모르겠습니다.

 

그러나 저는 반드시 지적해주고 싶은 부분은

습관적으로 indentity키를 pk로 잡는다라는 부분입니다.

 

이 부분은 쓸모에 따라서 잡힐수도 있고 아닐수도 있다는 것을 지적해주고 싶었고,

혹여 이게 정확하게 사용되고 있다면 다행이지만

불필요한 설정으로 용량만 늘렸던 경우가 있었습니다.

 

만약 이상도님께서 index에 대한 이해를 좀더 하셨으면 하는

충고를 드리는 것이었으니 나쁜 의미로 받아들이진 않았으면 합니다.

언제고 한번 만날 기회가 있다면 다른 것도 심도 있게 이야기를 할 수 있지 않을까 싶으네요 ^^

 

실례가 된 부분이 있다면 이해해주시기 바랍니다.

그럼 수고하시고 화이팅하십시오

 

여리님이 2005-03-08 18:13에 작성한 댓글입니다. Edit

안녕하세요..

kkk님 과 여리님,나그네님의 좋은 답변글 잘봤습니다.^&^

딴지는 아니고 잘못된 부분이 있는것 같아서..요..^^

create table 당시에는 클러스터 인덱스가 만들어 지지 않습니다.

RID 는 내부적으로 찾아가기 위한 정보입니다. 그것을 가지고 데이터를 정렬하여 저장 하지 않습니다.

 

그리고 자동증가 값에 PK(클러스터 인덱스) 를 주는 부분에 대해서는 그때 그때 마다 다르겠지만 단순히 좋은점은 페이지 분할이 발생 하지 않습니다. 상황에 따라 적절히 선택하시는게 좋을것 같습니다.

 

그리고  인덱스,아키텍쳐 부분에 대해서는 Inside SQL 2000 과 온라인 설명서를 추천 합니다!!

 

그럼 모두 즐거운 하루되세요.

 

 

송혁(hyok81)님이 2005-03-08 18:23에 작성한 댓글입니다.
이 댓글은 2005-03-08 18:23에 마지막으로 수정되었습니다.

음.. 그렇죠..

R-DBMS에서 정렬이 안되어 저장되는 것은 기본 중의 기본이죠.. ^^;;

 

좋은 지적 감사합니다~~~

 

clustered index가 만들어진다는 표현보다는 rid를 가지는 구조다라고 표현하는게 옳을 것 같네요..

어쨌던, 큰 흐름이 전달되었음 좋겠네요~

 

그럼..

길가는 나그네..님이 2005-03-08 19:17에 작성한 댓글입니다. Edit

kkk, 나그네, 여리님께 두루 감사드립니다.

어물쩡 가지고 있던 개념에 도장을 살짝 찍는듯한 답변 감사드립니다.

전문개발회사가 아닌 중소업체에서 단일규모 프로젝트를

진행하면서 5년이란 세월이 흐른지금 DB설계가 얼마나 중요한지

다시금 깨닫게되어 다시 한번 감사드립니다.

 

알면 알수록, 배우면 배울수록 어렵군요...^^;

이상도님이 2005-03-08 19:31에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
1811INNER JOIN 과 OUTER JOIN 간의 차이...? [4]
정원식
2005-03-09
7478
1810TM REQUEST 가 무엇인가여?
송승현
2005-03-09
3025
1809identity 가 포함된 테이블에 데이타 인서트 후 바로 Max identity 값을 가져오려 합니다.그런데... [3]
정원식
2005-03-08
3748
1808기본 키에 대한 개념 질문입니다. [10]
이상도
2005-03-07
6290
1807MS-SQL 서버간 LINK를 하면 사용자 LICENSE는 어떻게 되나요? [1]
전숙
2005-03-07
3037
1806ORACLE 테이블과 MS-SQL 테이블 조인하는 방법좀 가르쳐 주세요 [3]
TOM
2005-03-07
3236
1805SQL SERVER 관련 참고 사이트
채승룡
2005-03-03
3180
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.018초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다