중급4분 분량

DynamoDB의 제로 패딩 정렬 키

DynamoDB 문자열 사전순으로 정렬됩니다. 시간은 왼쪽에서 오른쪽으로 — 수치적으로는 아닙니다. 따라서 "10""2"보다 먼저 도착합니다. 왜냐하면 "1""2" 앞에 옵니다. 고정 너비에 대한 제로 패딩은 문자열을 만드는 방법입니다. 순서는 숫자 순서와 일치합니다.

DynamoDB 정렬 키에서 "10"이 "2"보다 먼저 정렬되는 이유는 무엇입니까?

DynamoDB 문자열 는 숫자가 아닌 UTF-8 바이트 순서에 따라 사전식으로 비교되기 때문입니다. "1"에 대한 바이트는 "2"보다 앞에 있으므로 "10""2" 앞에 위치합니다. 모든 숫자를 앞에 0으로 고정된 너비로 채우면 — "2""0000000002"가 됩니다 — 문자열 순서는 숫자 순서와 정확히 일치합니다.

  • 사전순: 문자열로 저장된 숫자는 단어처럼 정렬됩니다. "100", "11", "2" DynamoDB가 제공하는 순서입니다. 의도한 바는 아닙니다.
  • 수정 사항: 모든 숫자를 고정된 너비 앞에 0으로 채워서 "2"가 되도록 합니다. "0000000002"가 됩니다. 이제 사전식 순서와 숫자 순서가 일치합니다.
  • 너비를 한 번 선택하세요. 저장할 가장 큰 값으로 크기를 지정한 다음 추가하세요. 몇 자리. 나중에 너비를 변경한다는 것은 모든 키를 다시 작성하는 것을 의미합니다.
  • 무료 내림차순: 높은 순으로 정렬(리더보드 사례), 저장 maxValue - value, 역시 0으로 채워짐 — DynamoDB에는 속성별 정렬이 없습니다. 방향.

문자열 정렬 키가 당신을 배신하는 이유

SQL에서 정수 열에 대한 ORDER BY score DESC는 "그냥 작동합니다" — 엔진은 열이 숫자라는 것을 알고 있습니다. DynamoDB에는 그런 사치가 없습니다 Number 유형이 아닌 키입니다.

DynamoDB는 문자열(S) 정렬 키를 UTF-8 바이트 순서로 비교합니다. AWS sort-key documentation. 크기가 아닌 바이트입니다. "9" (0x39)는 첫 번째 바이트가 더 빠르기 때문에 "10"보다 순위가 높습니다. "1" (0x31). 길이는 관련이 없습니다. 첫 번째 다른 바이트만 결정됩니다.

이것이 바로 풋건입니다. 숫자가 문자열 정렬 키 안에 있는 순간, 모든 범위를 순회하는 Query는 뒤죽박죽된 것처럼 보이는 순서대로 행을 반환합니다.

리더보드 정렬 키 만들기

시즌별 아케이드 순위표를 살펴보세요. 매 시즌마다 1 씩 보유합니다. 플레이어가 뛰고 최고 점수를 먼저 원합니다.

단일 항목 컬렉션에서 로 모델링합니다.

  • leaderboardId (파티션 키) — 예: SEASON#2026-SPRING.
  • rankKey (정렬 키) — 제로 패딩된 점수와 순위 결정자.

순진한 첫 번째 시도는 원시 점수를 문자열로 저장합니다.

leaderboardIdrankKeyplayerHandle
SEASON#2026-SPRING"9"quickdraw
SEASON#2026-SPRING"10"ace_pilot
SEASON#2026-SPRING"1500"nightowl
SEASON#2026-SPRING"240"bytecrash

SEASON#2026-SPRINGQuery을 입력하면 다음 바이트 순서로 반환됩니다. "10", "1500", "240", "9". 9점슛은 마지막에 멈춰 있고 1500점짜리 달리기가 중간에 묻혀있습니다. 리더보드에는 쓸모가 없습니다.

고정된 너비로 패드

기록할 가장 큰 점수에 맞게 너비를 선택한 다음 왼쪽 패드를 누르세요. 0으로. 점수 상한선이 천만이라고 가정해 보세요. 이는 8자리이므로 10을 사용하세요. 헤드룸 숫자:

leaderboardIdrankKeyplayerHandle
SEASON#2026-SPRING"0000000009"quickdraw
SEASON#2026-SPRING"0000000010"ace_pilot
SEASON#2026-SPRING"0000000240"bytecrash
SEASON#2026-SPRING"0000001500"nightowl

이제 모든 키의 길이가 동일하므로 바이트별 비교 및 숫자 비교하면 동일한 순서가 생성됩니다. Query 오름차순은 9, 10, 240, 1500. 수학은 마침내 바이트와 일치합니다.

너비는 일방 통행 문입니다. 10자리까지 입력하고 나중에 점수가 이를 초과하는 경우 즉, 11자리 값은 10자리 값보다 먼저_ 정렬됩니다 — 모든 것을 다시 분리합니다 — 그리고 그것을 고치는 것은 기존의 모든 rankKey을 다시 쓰는 것을 의미합니다. 너비를 과도하게 제공합니다. 비용은 소수 바이트입니다.

내림차순 정렬: 차이를 저장

리더보드에서는 가장 높은 점수를 먼저 원합니다. DynamoDB는 정렬 키를 읽을 수 있습니다. ScanIndexForward: false를 사용하여 앞으로 또는 뒤로 이동하므로 일반적으로 하강은 읽기 시간 플래그 — 먼저 도달하세요.

그러나 하나의 항목 컬렉션이 혼합된 정렬 방향을 제공해야 하거나 읽기 플래그에 관계없이 물리적으로 최고 점수를 먼저 얻으려면 숫자 자체를 뒤집습니다. 동일한 너비로 제로 패딩된 maxValue - score를 저장합니다.

scoreinverted (9999999999 - score)rankKey
15009999998499"9999998499"
2409999999759"9999999759"
109999999989"9999999989"
99999999990"9999999990"

반전된 값에 대한 오름차순 바이트 순서는 이제 원래 점수를 생성합니다. 높음에서 낮음: 1500, 240, 10, 9. 그 비결은 바로 2007 Amazon Dynamo paper spirit — 키는 불투명한 바이트이므로 의도를 바이트로_ 인코딩합니다.

순위결정 추가

두 명의 플레이어가 동점을 이룰 수 있습니다. 패딩 처리된 점수가 정렬 키와 충돌하고 두 번째 write는 첫 번째(동일한 PK + SK)를 덮어씁니다. 고유한 접미사를 추가하여 각각 run은 별개의 항목이며 동점은 결정론적으로 해결됩니다.

rankKey = "<paddedScore>#<paddedTimestamp>#<playerId>"

예를 들어 "0000001500#0000001719100800#p_8842". 같은 점수, 이전 타임스탬프가 더 높은 슬롯을 차지합니다. 타임스탬프도 추가하거나 방금 수정한 정확한 버그입니다.

DynoTable에서는 제로 패딩된 rankKey로 정렬된 시즌 리더보드를 찾아볼 수 있습니다. 패딩된 값이 행을 올바르게 정렬하는지 확인하세요. 너비가 올바른지 증명하세요. 당신이 그들을 발송하기 전에.

복합 키를 손으로 조립하면 너비가 얇아지기 쉽습니다. 생성 KeyConditionExpression는 "시즌 최고" Query expression builderbegins_with /를 유지합니다. between 구문은 너비를 실험하면서 정직합니다.

0으로 채운 rankKey로 정렬된 시즌 리더보드를 DynoTable에서 탐색하는 모습.
0으로 채운 rankKey로 정렬된 시즌 리더보드를 DynoTable에서 탐색하는 모습.

피해야 할 함정

  • 패딩이 너무 좁습니다. 값이 처음으로 지정될 때 전체 구성표가 축소됩니다. 폭이 넘칩니다. 최악의 경우를 위한 크기에 숫자를 추가합니다.
  • 읽기 플래그를 잊어버렸습니다. 내림차순만 읽는 경우 ScanIndexForward: false가 필요한 전부일 수 있습니다. 플래그가 수행할 때 반전된 키에 도달하지 마십시오.
  • 하나의 컬렉션에 너비가 혼합되어 있습니다. 정렬 범위를 공유하는 모든 키는 같은 너비. 새 행을 채우고 이전 행을 채우지 않는 마이그레이션이 이를 인터리브합니다. 잘못.
  • 잘못된 세그먼트를 패딩합니다. 복합 키에서 모든 숫자 세그먼트를 패딩합니다. 순서에 참여하는 것 — 점수뿐만 아니라 점수와 타임스탬프도 모두 포함합니다.

다음 단계

제로 패딩은 더 넓은 범위의 도구 중 하나입니다. sort-key design 툴킷; 그것과 짝을 이루다 item collections 여러 서비스를 제공하기 위해 키에 과부하가 걸린 경우 패턴을 따르고, 정확한 Query에 기대어 Scan 순서가 맞으면.

Try DynoTable 실제 테이블을 탐색하고 제로 패딩 정렬을 확인하세요. 키는 스키마를 제공하기 전에 숫자 순서로 분류됩니다.

업데이트됨