인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

soap님의 프로필 이미지

작성한 질문수

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

Primary Key 생성 전략

PK 생성 전략의 '유니크 문자열 또는 숫자' 단점 부분 질문있습니다.

해결된 질문

작성

·

125

1

안녕하세요. 오늘도 인덱스 관련해서 질문을 들고 왔습니다!

(선생님이 "이런것도 질문해? 제발 질문 하지마 제발" 이라고 들 정도의 질문을 하는 학생들이 대부분 실력이 상승 한다고 해서 물음표 살인마가 되기로 했습니다.

지인들한테 강의 마구마구 홍보중입니다.. 한번만 봐주셉요..)

 

데이터 삽입 필요한 인덱스 페이지가 가득 찼다면 ,B+ tree 재구성 및 페이지 분할로 디스크 I/O 증가

정렬된 상태를 유지하기 때문에 삽입시마다 B+tree 재구성으로 인해 정렬로 인한 성능 저하 된다는건 이해가 되었습니다.(맞다면..) 허나 페이지 분할은 잘 이해가 안가네요 ㅠ

 

페이지 분할에 대해 제가 이해한 바인 아래 내용이 맞는지 궁금합니다.

PK가 AUTO_INCREMENT일 경우

  • 데이터가 항상 B+ Tree의 마지막(오른쪽 끝)에 삽입됨.

  • 하나의 페이지가 꽉 차면, 새로운 페이지가 오른쪽에 생성됨.

1. [ Page 1 ] (꽉 참) → 데이터 추가 시 분할 필요
2. [ Page 1 (반) ][ Page 2 (새로운 페이지 생성) ]

 

PK가 유니크 문자열 또는 숫자일 경우

랜덤한 값이 삽입될 때, 페이지가 꽉 차지 않았더라도 균형을 맞추기 위해 강제적으로 새로운 페이지가 만들어질 수 있음.

1. [ Page 1 ] (데이터 60% 차 있음) → 중간에 랜덤 값 삽입 시 균형 유지 필요
2. 균형 유지 과정에서 일부 데이터를 새로운 페이지로 이동하여 분산
3. [ Page 1 (30%) ][ Page 2 (새로운 페이지 생성) ]

 

즉, 유니크 문자열 또는 숫자는 페이지가 “완전히 가득 차지 않아도” 새로운 페이지가 생성될 수'도' 있다.

 

 

답변 2

2

쿠케님의 프로필 이미지
쿠케
지식공유자

dncjf64님, 안녕하세요!

 

일단, PK가 AUTO_INCREMENT든, 유니크 문자열 또는 숫자든,

페이지가 완전히 가득 차지 않아도 새로운 페이지가 생성될 수 있습니다.

해당 부분은 PK가 어떤 값인지와는 무관한 내용입니다.

 

그리고 페이지 분할에 대해 언급한 부분은, 랜덤키 vs 순차키의 차이라고 보시면 됩니다.

유니크 문자열 또는 숫자가 랜덤키, AUTO_INCREMENT가 순차키의 일종인 것이고요.

랜덤키는 페이지 분할이 순차키에 비해 더욱 잦을 수 있습니다.

말씀 주신 내용 보면 그 이유에 대해서는 이미 이해하신 것 같습니다.

B+ Tree가 정렬된 상태를 유지해야 하기 때문인데요, 

랜덤키는 중간에 삽입되는 상황이 많으므로 기존 데이터를 밀어내야 합니다.

그렇기 때문에 불필요한 페이지 분할이 더욱 자주 일어날 수 있습니다.

예를 들어, 10개의 페이지가 있고, 각 페이지는 1개의 데이터만 더 들어가면 페이지 분할이 일어날 수 있다고 가정해보겠습니다.

그리고, 랜덤키를 가지는 10개의 데이터가 각 페이지로 들어가면, 10번의 삽입 모두 페이지 분할이 일어날 수 있습니다.

분할된 페이지는 당장의 필요에 의해 분할이 일어났으나, 신규 데이터는 들어가지 않고 페이지 공간이 낭비될 수도 있습니다.

반면, 순차키는 마지막 페이지에만 추가하기 때문에, 항상 균등하게 페이지 분할이 일어나고 예측이 가능합니다.

 

아래는 조금 부가적인 내용인데요,

그렇다면 순차키가 랜덤키보다 삽입 속도가 항상 빠른가? 라는 의문이 생길 수 있습니다.

위 내용을 보면 그렇게 느껴질 수 있거든요.

근데 꼭 그렇지 않을 수도 있습니다.

쓰기 트래픽이 아주 크다면, 순차키에서 우측 특정 노드에만 데이터 삽입이 될 때 right growing index 문제가 발생할 수 있습니다.

이 경우, 디스크 I/O 작업이 병목이 생기면서 랜덤키가 더 빠를 수도 있을 것 같네요.

물론, 쓰기 트래픽이 그 정도로 높으면 관계형 데이터베이스(B+ Tree index)를 고려하지 않는 게 나을 수도 있습니다.

이건 직접 테스트를 해본건 아니라, 이론 상 그럴 수도 있다는 것이고, 궁금하신 부분은 직접 테스트해보시거나 추가적으로 학습해 나가시면 좋을 것 같네요!

일단 대부분의 경우에서는 순차키가 삽입 속도는 더 빠르다고 생각하시면 될 것 같습니다.

 

궁금한 건 질문하는 자세 아주 좋습니다 ㅎㅎㅎ

다만, 데이터베이스는 단편적으로 학습하는 것보다, 책으로 깊이 있게 학습하는 것도 추천드립니다!

사실 이론적인 부분은 저도 다 알 수가 없고, 인터넷 또는 공식 문서에서 자료를 찾아보고 직접 테스트해보는게 더 정확할 수 있습니다.

결국 이론은 차근차근 체계적으로 학습하는게 효율이 더 좋은 것 같더라고요.

혹시 더 궁금한 점 있으시면 편히 문의 주세요!

soap님의 프로필 이미지
soap
질문자

책장에 장식으로 꽂아두던 real mysql을 꺼내서 봐야겠네요..

답변 감사합니다앗~!

2

김현진님의 프로필 이미지

안녕하세요 ? 저도 정보를 얻고자 질문 게시판 돌아다니면서 흥미로운 질문이 있어서 대신 답변 남깁니다. . !

(수강생 입장이라 부정확할 수 있는 점 양해 부탁드려요)


질문 주신 내용은 B+ Tree에서 데이터가 삽입되는 경우

(특히 정렬된 값이 아니라 랜덤한 값을 넣는 경우 페이지가 꽉 찬 상태가 아니더라도 페이지가 새로 생성될 수 있다)

 

그럴 것 같습니다 !
왜냐하면 MySQL의 경우 B+ Tree의 데이터 단위가 기본적으로 16kb의 페이지 단위로 가지고 있는데
B+ Tree를 정렬 상태를 유지해야 하므로 페이지가 꽉 차 있음 여부와 별개로 새로운 페이지를 추가해야 하는 상황이 있다면 페이지를 추가할 것 같습니다.

그렇게 생각하는 이유는 다음과 같은데요.

 

Page에 정해진 상한과 하한의 경계가 있을 수 있다.
말씀하시는 데이터는 사실 리프 노드이고 이러한 리프 노드는 브랜치 노드에 의해서 분류가 됩니다.
그런데 사실 브랜치 노드에 의해서 분류가 되기 때문에 결국 리프 노드에 값이 들어갈 수 있는 상한과 하한이 있을 수 있을 것 같습니다.
따라서 이 내용은 페이지의 꽉 차 있음과 별개로 새로운 데이터를 생성할 수 있을 것 같습니다.

 

AUTO INCREMENT 와 PK 유니크
데이터가 항상 정렬된 순서로 삽입되는지가 중요한 것 같습니다.
강의에서 소개된 SnowFlake 같은 경우 앞 12비트가 타임스탬프로 되어 있으므로 항상 정렬된 순서로 삽입될 확률이 높습니다.
그래서 이해하신 내용을 더 엄밀하게 분류하면 항상 정렬된 데이터가 삽입되는지 (AUTO INCREMENT는 당연히 1씩 증가하므로 항상 정렬된 상태를 보장함) 정렬되지 않은 랜덤한 값이 삽입되는지가 더 중요한 여부일 것 같습니다 !

 

결론
위 내용을 토대로 다시 정리해 보면 정렬되지 않은 랜덤한 데이터가 삽입된다면 (유니크 문자열, 숫자와 별개로) 페이지가 꽉 차지 않더라도 새로운 페이지가 추가될 수 있을 것 같습니다.

그 이유는 리프 노드에 삽입되는 기준은 사실 브랜치 노드의 키값인데, B+ Tree의 동작 방식을 생각해보면 어떤 특정 리프 노드는 상한과 하한값을 가지고 있을 수 있는데 그렇기 때문에 페이지가 꽉참 여부와 별개로 새로운 페이지가 추가될 수 있음

쿠케님의 프로필 이미지
쿠케
지식공유자

답변 도움 감사합니다~!

soap님의 프로필 이미지
soap
질문자

어휴 감사합니다. 단번에 이해했습니닷!

soap님의 프로필 이미지

작성한 질문수

질문하기