pile·
백엔드·8퍼센트8퍼센트·

날짜 구간에 값을 매핑하는 방법 (그리고 RangeKeyDict)

날짜 구간별로 다른 값을 적용해야 할 때 코드를 어떻게 쓰는 게 나은지 세 가지 버전을 비교하는 짧은 글이다. if 비교문에서 시작해 날짜와 값의 쌍 목록을 거쳐, 범위를 키로 쓰는 RangeKeyDict로 정리한다. 포인트 적립률 정책을 예제로 삼는다.

핵심 포인트
  • 날짜 구간 매핑을 if 비교문으로 짜면 구간이 바뀔 때마다 로직을 고쳐야 하고 눈으로 읽기 어렵다.
  • 날짜와 값의 쌍을 목록으로 빼면 로직 대신 데이터를 고치게 되지만 내림차순 정렬 전제가 자연스럽지 않다.
  • range-key-dict 패키지의 RangeKeyDict는 시작과 끝 튜플을 사전의 키로 쓸 수 있게 해준다.
  • RangeKeyDict를 쓰면 조회 함수가 사전 인덱싱 한 줄로 줄어든다.
  • 날짜뿐 아니라 자주 바뀌는 법령이나 정책처럼 어떤 범위에 값을 매핑할 때 두루 쓸 수 있다.
상세 정리
  • 예제 상황: 포인트 적립 정책이 2020년 1월 1일부터 1퍼센트, 2월 2일부터 2퍼센트, 8월 8일부터 8퍼센트로 바뀐다고 가정한다.
  • 1안 구현: base_date를 받아 경계 날짜와 차례로 비교하며 Decimal 값을 반환하는 함수다. 시작일 이전은 None을 돌려준다.
  • 1안의 문제 1: 구간이 바뀔 때마다 비교식 자체를 수정해야 한다.
  • 1안의 문제 2: 코드가 한눈에 들어오지 않는다. 특정 날짜의 적립률이 2퍼센트인지 8퍼센트인지 자세히 보지 않으면 헷갈린다는 것이 저자의 지적이다.
  • 2안 발상: 날짜와 값을 쌍으로 지정해 두고 그 안에서 날짜를 맞추는 방식이다.
  • 2안 구현: 적용 날짜를 내림차순으로 나열한 튜플 목록을 만들고 순회하며 적용일이 기준일 이하인 첫 항목의 값을 반환한다. 마지막 항목은 date.min과 None으로 채워 기본값 역할을 맡긴다.
  • 2안의 이득: 매핑이 로직이 아니라 값으로 빠져 구간 변경이 데이터 수정으로 끝난다.
  • 2안의 아쉬움: 내림차순 입력을 전제해야 해서 일반적인 오름차순 감각과 어긋나고 조회 함수 자체도 한 번 더 읽어야 이해된다.
  • 3안 도입: 동료의 제안으로 RangeKeyDict를 쓰게 됐다. 값의 범위를 사전의 키로 사용할 수 있는 매핑 컬렉션이다.
  • 설치와 사용: pip로 range-key-dict을 설치하고 시작과 끝 튜플을 키로 하는 사전 형태로 매핑을 정의한다.
  • 3안 구현: date.min부터 2020년 1월 1일까지는 None, 이후 구간마다 각 적립률을 두고 마지막 구간의 끝을 date.max로 열어둔다. 조회 함수는 사전에 기준일을 넣는 것이 전부다.
  • 검증: 세 구현 모두 같은 assert 묶음을 통과한다. 경계일 당일이 새 값에 해당하는지까지 확인한다.
  • 적용 범위: 날짜에 한정되지 않으며 어떤 범위에 값을 매핑하는 상황이면 쓸 수 있다.
  • 가독성 관점: 세 구현 모두 같은 정책을 표현하지만 3안은 어느 구간에 어떤 값이 붙는지가 선언부에서 그대로 읽혀 코드를 따라 실행해볼 필요가 없다.
  • 경계 처리: 1안은 미만 비교를 쌓아 올리고 2안은 이하 비교로 뒤집는데, 3안은 시작과 끝을 명시하므로 경계가 어느 쪽에 속하는지 헷갈릴 여지가 줄어든다.
왜 읽나정책 변경 이력을 if 사다리로 관리하고 있다면 범위를 키로 쓰는 사전으로 옮기는 작은 리팩터링 패턴을 바로 적용할 수 있다.
8퍼센트
8퍼센트 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·twilio-engTwilio Engineering·

    Programmable Messaging에서 Verify API로 마이그레이션하기

    Twilio의 Programmable Messaging API로 자체 OTP 솔루션을 운영하던 서비스가 Verify API로 전환하는 방법을 코드 예시와 함께 설명한다. Verify는 OTP 전송·검증을 위한 전용 API로, 전화번호 구매, 토큰 생성, DB 저장·만료 관리를 내부에서 처리해 개발자가 직접 구현할 코드를 크게 줄인다.

    요약 이어보기
    #authentication#twilio#sms+2
  2. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 2부

    포스타입 백엔드 엔지니어가 벡터 기반 개인화 추천 시스템을 실제 운영하며 맞닥뜨린 성능 장애와 용량 문제를 해결한 과정을 담은 2부다. 수백만 개의 벡터 KNN 검색이 피크 시간대에 전체 Elasticsearch 검색 성능을 흔드는 문제부터 클러스터 OOM 사태까지, 쿼리 최적화와 인프라 분리 두 가지 경로로 근본 해결에 이른다.

    요약 이어보기
    #elasticsearch#vector-search#recommendation-system+2
  3. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 1부

    포스타입이 태그 기반 추천의 한계를 극복하고 벡터 임베딩 기반 개인화 추천 시스템을 구축한 과정을 담은 1부다. 유사한 콘텐츠가 다른 용어를 쓰거나 동일한 태그가 전혀 다른 톤의 콘텐츠를 가리키는 문제를 임베딩 벡터로 해결하고, OpenSearch의 HNSW ANN 검색으로 수백만 벡터를 실시간 검색하는 시스템을 구축해 구매율 15% 향상을 달성했다.

    요약 이어보기
    #opensearch#vector-search#recommendation-system+2