중급4분 분량

DynamoDB의 복합 정렬 키

는 파티션 키에 정렬 키를 더한 것입니다. 이를 강력하게 만드는 요령은 정렬 키 안에 무엇을 넣느냐입니다: 계층 구조를 구분자로 이어붙인 하나의 문자열로 인코딩하면, 단일 Query가 서브트리 전체를 정렬 순서대로 읽습니다 — 조인도, 재귀도, 두 번째 왕복도 없이.

DynamoDB에서 복합 정렬 키는 어떻게 동작하나요?

복합 정렬 키는 계층 구조를 구분자로 이어붙인 하나의 문자열 — root/photos/2026/ — 에 담고, DynamoDB는 이를 UTF-8 바이트 순서로 저장합니다. 그 배치가 이미 트리와 일치하므로, begins_with(SK, "root/photos/")를 쓴 단일 Query가 서브트리 전체를 경로 순서대로 읽습니다. 조인도, 재귀도, 두 번째 왕복도 없이 — 인접한 에 대한 접두사 스캔일 뿐입니다.

  • 정렬 키는 단순한 ID가 아니라 정렬 가능한 문자열입니다. 경로를 그 안에 담으세요 — root/photos/2026/ — 그러면 DynamoDB가 파티션의 아이템을 UTF-8 바이트 순서로 자동 정렬합니다.
  • 구분자는 접두사 매칭을 서브트리 읽기로 바꿉니다. begins_with(SK, "root/photos/")는 그 폴더의 모든 하위 항목을 한 번의 쿼리로 반환합니다.
  • 정렬 키는 범위 조건을 지원하지, 임의의 필터는 지원하지 않습니다. begins_with, between, >, <가 제공됩니다 — 필요한 읽기가 Scan이 아니라 접두사나 범위가 되도록 키를 설계하세요.
  • 구분자는 핵심을 담당합니다. 경로 세그먼트 안에 나타날 수 없는 것을 고르세요. 그러지 않으면 서로 무관한 두 가지가 충돌합니다.

정렬 키가 승부의 전부인 이유

SQL에서 넘어왔다면 폴더 트리를 parent_id 셀프 조인으로 모델링하고 재귀적으로 순회할 겁니다 — 레벨마다 쿼리 한 번씩. DynamoDB에서 그것은 조인이 없는 키-값 저장소를 상대로 한 N+1 지뢰입니다.

DynamoDB는 모든 아이템을 파티션 키 아래에서 정렬 키로 정렬해 저장하며, 문자열은 UTF-8 바이트 순서로 저장합니다 (AWS: Query 키 조건). 따라서 정렬 키가 경로라면, 물리적 배치가 이미 트리와 일치합니다. 읽기는 그래프 순회가 아니라 인접한 슬라이스에 대한 접두사 스캔이 됩니다.

바로 그 발상의 전환입니다: 정렬 키는 정확히 일치시키는 식별자가 아닙니다. 그것은 정렬 가능한 주소입니다. 그것을 잘 설계하면 쿼리는 저절로 따라옵니다.

파일 시스템 트리 모델링하기

계정별 파일 트리를 저장한다고 해봅시다. 계정당 하나의 드라이브가 자연스러운 파티션이고, 그 안의 경로가 정렬 키입니다.

PKSKnode_typebytes
DRIVE#a91root/folder-
DRIVE#a91root/docs/folder-
DRIVE#a91root/docs/taxes.pdffile88210
DRIVE#a91root/photos/folder-
DRIVE#a91root/photos/2026/folder-
DRIVE#a91root/photos/2026/beach.jpgfile284910
DRIVE#a91root/photos/2026/sunset.jpgfile512004

여기서 두 가지 고유한 규칙이 일을 하고 있습니다:

  • PK = DRIVE#<account>는 한 계정의 트리 전체를 하나의 에 유지하므로, 어떤 서브트리 읽기든 단일 파티션 Query가 됩니다.
  • SK는 전체 경로이며 폴더에는 끝에 /가 붙습니다. 그 끝의 슬래시는 의도적입니다 — 폴더가 자기 자식들보다 앞에 정렬되게 하고, root/photos/root/photos라는 이름의 형제 파일과 구분되게 합니다.

서브트리를 한 번의 쿼리로 읽기

root/photos/ 아래의 모든 것 — 폴더, 하위 폴더, 파일 — 을 재귀적으로 나열하세요:

Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive   = "DRIVE#a91"
:prefix  = "root/photos/"

이는 root/photos/, root/photos/2026/, beach.jpg, sunset.jpg를 — 경로 순서대로, 하나의 과금된 읽기로 — 반환합니다. 드라이브 전체가 아니라 그 슬라이스의 아이템에 대해서만 비용을 지불합니다.

DynoTable에서는 바로 이 begins_with 쿼리를 경로 정렬 키에 실행하면 폴더와 그 하위 항목이 경로 순서대로 돌아옵니다 — 손으로 써야 할 자리표시자 구문 따위 없이.

원시 KeyConditionExpression(이름, 값, begins_with)을 직접 코드에 넣어야 하나요? DynamoDB 표현식 빌더에서 만들고 복사하세요.

DynoTable에서 경로 정렬 키에 begins_with 쿼리를 실행해, 폴더와 그 하위 항목을 경로 순서대로 반환하는 모습.
DynoTable에서 경로 정렬 키에 begins_with 쿼리를 실행해, 폴더와 그 하위 항목을 경로 순서대로 반환하는 모습.

서브트리 전체가 아니라 한 단계만 나열하기

begins_with재귀적 읽기를 줍니다. 재귀적이지 않은 디렉터리 나열 — root/photos/의 직속 자식만, 그보다 깊은 것은 제외 — 을 하려면 depth 속성을 저장하고 정렬 키 범위에 필터를 더하거나, 경로를 parent GSI로 분리하세요. 가장 단순한 방법은 parent 속성 (root/photos/)을 유지하고 그것을 키로 하는 GSI를 두는 것입니다.

요점: 정렬 키는 접두사범위 질문에 저렴하게 답합니다. "직속 자식만"은 다른 질문입니다 — FilterExpression이 효율적이길 바라지 말고 명시적으로 모델링하세요. 필터는 읽기 이후에 실행되고, 버리는 아이템 하나하나에 대해 비용을 지불합니다.

구분자를 신중하게 고르기

구분자는 여러분의 데이터 계약의 일부입니다. 두 가지 규칙:

  • 경로 세그먼트 안에 절대 나타나서는 안 됩니다. 파일명에 /가 들어갈 수 있다면 /는 잘못된 구분자입니다 — a/b라는 파일은 b를 담은 폴더 a와 구별되지 않습니다. 예약된 바이트(어떤 팀은 #나 제어 문자를 씁니다)를 고르고 세그먼트에서는 금지하세요.
  • 경계에서의 정렬 순서에 유의하세요. /(0x2F)는 숫자와 문자보다 앞에 정렬되며, 보통 트리 순서에서 원하는 결과입니다. 구분자를 바꾸면 정렬 순서가 바뀝니다 — 실제 데이터로 검증하세요.

복합 정렬 키 vs. 별도의 정렬 속성

복합 정렬 키 (root/photos/2026/x)순수 ID 정렬 키 + parent 속성
서브트리 읽기begins_with 쿼리 한 번재귀 쿼리(N+1) 또는 GSI 순회
정렬경로 순서, 공짜명시적 정렬 속성을 추가해야 함
이동 / 이름 변경모든 하위 항목 재작성parent 포인터 하나 갱신
직속 자식 나열depth 속성 또는 GSI 필요자연스러움 (parent = x)

복합 키는 읽기가 서브트리 모양이고 정렬이 중요할 때 이깁니다. 플랫 ID 모델은 트리가 끊임없이 변할 때 이깁니다. 읽기가 많은 대부분의 계층 구조 — 파일 트리, 카테고리 트리, 조직도 — 는 복합 쪽으로 기웁니다.

함정과 다음 단계

  • 키에 과하게 욱여넣지 마세요. 인코딩하는 모든 것은 불변이며 접두사로만 인덱싱됩니다. 등호로 쿼리하는 속성은 정렬 키에 밀어 넣을 게 아니라 각자의 필드나 GSI에 있어야 합니다.
  • 정렬 키는 임의의 WHERE를 할 수 없습니다. 오직 begins_with, between, 비교 연산자뿐입니다. FilterExpression에 손이 간다면 십중팔구 키를 잘못 모델링한 것입니다 — Query vs. Scan을 보세요.
  • 키 설계를 더 깊이 파는 내용단일 테이블 설계에 있습니다. 서브트리 읽기에 기본 테이블이 아니라 인덱스가 필요한 경우는 GSI vs. LSI를 보세요.

표현식 빌더에서 begins_with 키 조건을 만든 다음, DynoTable을 내려받아 자신의 테이블에 이 접두사 쿼리를 실행하고 서브트리가 경로 순서대로 돌아오는 것을 지켜보세요. (그리고 SQL에 두고 온 셀프 JOIN은요? 필요할 때는 DynoTable의 SQL Workbench가 여전히 실행해 줍니다.)

업데이트됨

이 디자인을 인터랙티브하게 사용해 보세요

무료 DynamoDB 싱글 테이블 디자인 도구에서 엔터티와 액세스 패턴을 스케치해 보세요 — PK/SK 키 템플릿을 제안하고, 항목 컬렉션을 미리 보여주며, 어떤 패턴이 GSI를 필요로 하는지 보여줍니다.

싱글 테이블 디자인 도구 열기