강의

멘토링

로드맵

Inflearn brand logo image

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

리나님의 프로필 이미지
리나

작성한 질문수

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

Primary Key 생성 전략

실무에서 Primary Key 생성 전략 질문 있습니다.

해결된 질문

작성

·

274

·

수정됨

0

Primary Key 생성 전략에서 많은 것들을 알기 쉽게 설명해주셔서 감사합니다 🙂

 

제가 개인적으로 생각하는 가장 베스트 방법 2가지만 설명 드리도록 하겠습니다.

 

  1. Primary Key 값을 Snowflake 알고리즘으로 해결

  • 장점

    • 인덱스 탐색에 있어서 정렬된 순서로 차례대로 저장 하다보니 범위 검색에 있어서 장점이 될 수 있다.

  • 단점

    • Secondary Index 생성시 각각 Leaf Node 에 PK 값 (포인터) 를 가지고 있다보니 아무래도 생성된 Snowflake 알고리즘 값은 길이가 길어서 인덱스 저장용량이 증가 될 수 있다.

  1. PK 생성 전략을 Auto_Increment 로 하고 샤딩키(article_id) 값을 Snowflake 알고리즘으로 설정 해서 저장 한다. (단 client 에게는 PK 값 대신 article_id 으로 노출 한다.)

  • 장점

    • Secondary Index 생성시 각각 Leaf Node 에 PK 값 (포인터) 값이 용량이 작아 인덱스 저장 용량 부담이 없다.

    • 인덱스 탐색에 있어서 정렬된 순서로 차례대로 저장 하다보니 범위 검색에 있어서 장점이 될 수 있다.

  • 단점

    • client 으로 부터 요청시 샤딩키(article_id) 값으로 데이터 조회를 해야 하기 떄문에 Secondary Index -> Clustered_Index 까지 두번 인덱스 트리를 탐색 해야 하는 단점이 있다.

 

일단 이렇게 각각의 장단점을 설명 드렸습니다.

여기서 제가 궁금한것은 실무에서 데이터베이스 테이블 설계시 이 두가지 방법 중 하나를 선택 하는데 있어서 각각 어떤 경우에 적합한지 판단 내리기가 힘든 부분이 있습니다.

 

각각 케이스 마다 장단점을 알고 있지만 아무래도 자세하게 수치화 된 지표 가 없어 선택하는데 있어서 어려움이 있는데요.

선생님 경우는 실무에서 이 두가지 중 선택시 어떤 경우에 적절하게 판단 하시는지 노하우를 알려주시면 정말 감사 하겠습니다 🙂

 

답변 2

2

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

리나님, 안녕하세요!

 

일단, AUTO_INCREMENT PK와 Snowflake 크기 차이에 대한 오해가 있는듯 하여, 이 부분 먼저 언급 드려보겠습니다.

Snowflake는 64비트를 사용합니다.

AUTO_INCREMENT PK는 INT 타입으로 정의하면 32비트로 사용할 수도 있지만,

대규모 시스템에서는 데이터가 많다면 INT 타입의 식별자는 금세 고갈될 수 있기 때문에 처음부터 64비트를 고려하는 경우가 많습니다.

따라서, 둘다 64비트로 PK를 정의한다면, 언급해주신 문제에 대해서는 읽기 성능 문제만 남으므로 1번으로 처리하는게 유리합니다.

 

아무튼 질문 자체는, 2번 상황에서의 PK를 INT 타입(32비트)로 정의하는 등 PK의 크기 차이가 나는 상황이라고 가정해보겠습니다.

읽기/쓰기 트래픽 차이로 인한 트레이드오프가 생길 것 같은데요.

읽기 트래픽이 많다면 당연히 데이터(클러스터드 인덱스)에 즉시 접근하는게 더 빠르기 때문에 1번이 더 나을 수 있습니다.

그런데 또, 데이터베이스 앞단에 캐시를 붙이는 시스템 구성이라면, 최종 클라이언트 입장에서 사실 세컨더리 인덱스 한번 더 타는 것 정도는 2번과 성능 면에서 크게 유의미하지 않을 수 있습니다.

특히 클라이언트가 사람이라면 이 차이가 느껴지지도 않을 것이고요.

 

그런데 반대로 2번이 쓰기 트래픽이 빠른 것도 아닙니다.

인덱스로 인해 쓰기 시점에 부가적인 비용도 생기기도 하고,

AUTO_INCREMENT를 사용하면 순차적인 채번을 위해 동시 쓰기 요청이 들어왔을때 락 경합이 생길 수 있습니다.

이러한 락을 방지하기 위한 데이터베이스 내부 설정들이 있긴 하지만(반드시 1씩 순차 증가하진 않도록 하는 등.. 저도 사용해보진 않았습니다),

이를 위해 데이터베이스 설정을 변경 및 관리해줘야하는 번거로움은 생기고요.

(강의에서는 분산 환경에서의 PK 전략을 설명하는 것에 조금 더 초점을 두었기 때문에 AUTO_INCREMENT 성능에 대해서는 따로 다루진 않았는데, 궁금하시면 한번 찾아보셔도 좋을 것 같습니다!)

하지만 이런걸 문제로 볼 정도로 쓰기 트래픽이 많지 않다면, 마음 편하게 AUTO_INCREMENT PK 생성하는게 간단하긴 합니다.

저장 용량에 대해서는, 인덱스가 많이 생성될 수 있으면 당연히 PK가 작은게 유리하겠지만,

테이블이 작게 유지되거나 강의 뒷편에서 배울 캐시 또는 CQRS를 적용한다면, 어차피 테이블 하나에 인덱스가 많이 생성될 일은 없을 수 있습니다.

저장소 자체 비용은 크게 비싸지 않기 때문에, 인덱스가 조금 더 크다고 해서 문제될 요소는 딱히 없을 수 있고요.

 

결론은, 뭐가 더 낫다라는 정답은 없고,

실제 들어오는 데이터와 트래픽, 서비스 특성, 시스템 구성을 모두 종합적으로 고려해서 테스트를 진행해야 구체적인 차이를 얻을 수 있을 것 같고, 아무튼 이러한 부분에 대해 인지하고 필요할 때 적용할 수 있으면 충분하다고 봅니다.

 

그런데 대부분의 경우에서는 정말로 반드시 이걸로 해야된다라는 유의미한 차이는 없을 것 같고요.

그래서 실무 관점에서 조금 더 현실적으로 말씀드리면,

시스템 구성에서 크게 유의미한 차이나 문제가 없을 것 같다면, 기존 팀에서 이미 선택했던 전략 또는 팀원들이 선호하는 방향을 따라가는 경우가 많네요.

또, 강의에서는 MySQL 단일 컨테이너로 진행하긴 했지만, 실제로 사용하는 데이터베이스의 정책에 따라서 내부적으로 PK를 특정 전략으로 강제해버리는 경우도 있고요. 이 경우에는 선택권이 없을 수도 있습니다.

 

저는 직접 강의로 만들면서 시스템 구성하는 입장이어서 이론 상 또는 유지보수 측면에서 유리한 점이 많은 1번 전략을 취했다고 보시면 되고, 

실무에서도 특별한 이유가 없고 결정권이 온전히 저에게 있다면, AUTO_INCREMENT 사용하는 것보단 1번 전략을 취할 것 같네요.

그런데 또 뭘 쓰든 아무 상관 없는 트래픽 작고 가벼운 테이블이라면 AUTO_INCREMENT를 쓰기도 할 것 같습니다.

 

실무에 들어가면, 정형화된 정답이 있는 경우는 많이 없네요.

그래서 강의에서도 범용적인 내용으로 설명하려다보니 구체적인 수치에 대해서는 언급하지 않게 된 것도 있고요.(상황이 조금만 달라져도 어차피 무의미한 내용이 될 수 있으므로)

각각 장단점 인지해서 상황에 맞게 적절한 해답을 찾아가게 되는 것 같습니다!

 

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

 

약간 다른 이야기인데 리나님의 이전 질문에서도 느꼈지만,

강의 내용을 기계적으로 그대로 따라오는게 아닌, 스스로 계속 고민하면서 더 나은 방안을 찾아보려고 하시는 것 아주 좋습니다!! 👍

리나님의 프로필 이미지
리나
질문자

답변 감사합니다!! 이해 쉽게 설명 해주셔서 정말 감사드립니다.

AUTO_INCREMENT 통해 Long (64비트) 하고 Snowflake는 64비트 하고 차이가 없다고 말씀해주셨는데요!

 

제가 착각을 한 부분이 있었던것 같습니다.

 

AUTO_INCREMENT 통해 Long (64비트) "1" 로 저장 되는 row 값이 존재한다고 하면

해당 테이블 Secondary Index의 Leaf Node 에 클러스터링 키 (포인터 또는 PK 값) 이 64비트로 저장 안하고 더 작은 비트로 저장 되는 걸로 착각 했나 봅니다. (PK 값 "1" 로 저장해도 세컨더리 인덱스의 Leaf Node에 저장되는 PK 값이 64비트로 저장 된다는 말씀이시죠?)

 

 

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

네, 말씀하신게 맞습니다!

수가 작더라도 컬럼에 정의한 데이터 타입에 의해 모두 동일하게 64비트를 사용하게 됩니다!

0

안녕하세요, 인프런 AI 인턴입니다. 리나님.

질문하신 내용은 데이터베이스 설계 시 Primary Key 생성 전략에 관한 매우 중요한 주제를 다루고 있습니다. Snowflake 알고리즘과 Auto Increment 전략의 장단점을 비교해주셨는데, 실무에서의 선택 기준에 대해서는 몇 가지 고려사항을 말씀드리겠습니다.

1. Snowflake 알고리즘

  • 적합한 경우:

    • 고가용성과 고성능이 필요한 대규모 시스템.
    • 고유성이 보장된 분산 환경에서의 키 생성이 필요한 경우.
    • PK의 크기가 커져서 저장 공간이 다소 증가하더라도, 시스템의 확장성 및 범위 쿼리 성능이 중요한 경우.
  • 고려 사항:

    • 확장 가능한 분산 환경 구축이 전제되어야 함.
    • 인덱스 크기가 커질 수 있기 때문에, 저장 용량에 대한 적절한 모니터링 필요.

2. Auto Increment 및 Snowflake 기반의 Sharding Key

  • 적합한 경우:

    • 데이터베이스가 비교적 단일 인스턴스 혹은 수평적 확장이 덜 요구되는 경우.
    • 쉽게 관리가 가능하고, PK의 크기를 줄여 저장 용량을 극대화하고자 할 때.
    • 클라이언트에게 노출되는 키에 대한 보안이나 체계적인 관리가 필요한 경우.
  • 고려 사항:

    • 샤딩이 필요한 경우, Sharding Key로 Snowflake 알고리즘을 사용하여 확장성을 강화.
    • 부하 분산 및 데이터 접근의 효율성을 고려하여 설계.

각각의 방법은 서로 다른 시스템 환경과 요구 사항에 따라 적합성이 달라집니다. 실무에서 어떠한 키 생성 전략을 선택할지는 데이터의 특성, 시스템의 규모, 확장성 요구사항, 관리의 용이성 등을 종합적으로 평가하여 결정해야 합니다. 전반적으로, 수치를 통한 평가보다는 시스템의 구조적 요구 및 관리 용이성을 중심으로 합리적인 선택을 하는 것이 중요합니다.

추가적으로 다양한 실사례를 참고하실 수 있는 인프런 커뮤니티 포스트를 추천드립니다:
- 효율적인 PK 생성 전략의 선택 (게시글 제목)

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

리나님의 프로필 이미지
리나

작성한 질문수

질문하기