Composite Sort Key di DynamoDB
adalah partition key plus sort key. Trik yang membuatnya kuat adalah apa yang Anda taruh di dalam sort key: enkode
sebuah hierarki sebagai satu string berdelimiter, dan satu Query membaca seluruh subtree
dalam urutan terurut — tanpa join, tanpa rekursi, tanpa perjalanan bolak-balik kedua.
Bagaimana composite sort key bekerja di DynamoDB?
Sebuah composite sort key mengemas sebuah hierarki ke dalam satu string berdelimiter — root/photos/2026/ — yang disimpan DynamoDB dalam urutan byte UTF-8. Karena tata letaknya sudah cocok dengan pohonnya, satu Query dengan begins_with(SK, "root/photos/") membaca seluruh subtree dalam urutan path. Tanpa join, tanpa rekursi, tanpa perjalanan bolak-balik kedua — hanya sebuah prefix scan atas sebuah yang bersambung.
- Sort key adalah string yang terurut, bukan sekadar sebuah ID. Kemas sebuah path
ke dalamnya —
root/photos/2026/— dan DynamoDB menyimpan item-item partisi itu dalam urutan byte UTF-8 secara otomatis. - Sebuah delimiter mengubah pencocokan prefix menjadi pembacaan subtree.
begins_with(SK, "root/photos/")mengembalikan setiap turunan dari folder itu dalam satu query. - Sort key mendukung kondisi rentang, bukan filter sembarang. Anda mendapat
begins_with,between,>,<— rancang key-nya sehingga pembacaan yang Anda butuhkan adalah sebuah prefix atau sebuah rentang, bukan sebuahScan. - Delimiter itu menanggung beban. Pilih satu yang tak bisa muncul di dalam segmen path, atau dua cabang yang tak berkaitan akan bertabrakan.
Mengapa sort key adalah seluruh permainannya
Datang dari SQL, Anda akan memodelkan sebuah pohon folder dengan self-join parent_id dan
menjelajahinya secara rekursif — satu query per level. Di DynamoDB itu adalah jebakan N+1
terhadap sebuah key-value store yang tak punya join.
DynamoDB menyimpan setiap item di bawah sebuah partition key, terurut menurut sort key-nya, dalam urutan byte UTF-8 untuk string (AWS: Query key conditions). Jadi jika sort key Anda adalah path-nya, tata letak fisiknya sudah cocok dengan pohonnya. Sebuah pembacaan menjadi sebuah prefix scan atas potongan yang bersambung — bukan sebuah penjelajahan graf.
Itulah pergeserannya: sort key bukanlah sebuah pengidentifikasi yang Anda cocokkan persis. Ia adalah sebuah alamat yang terurut. Rancang ia dan query-nya jatuh dengan sendirinya.
Memodelkan sebuah pohon sistem berkas
Katakanlah Anda menyimpan pohon berkas per akun. Satu drive per akun adalah partisi yang alami; path di dalamnya adalah sort key-nya.
| PK | SK | node_type | bytes |
|---|---|---|---|
| DRIVE#a91 | root/ | folder | - |
| DRIVE#a91 | root/docs/ | folder | - |
| DRIVE#a91 | root/docs/taxes.pdf | file | 88210 |
| DRIVE#a91 | root/photos/ | folder | - |
| DRIVE#a91 | root/photos/2026/ | folder | - |
| DRIVE#a91 | root/photos/2026/beach.jpg | file | 284910 |
| DRIVE#a91 | root/photos/2026/sunset.jpg | file | 512004 |
Dua konvensi orisinal yang mengerjakan pekerjaannya di sini:
PK = DRIVE#<account>menjaga seluruh pohon satu akun dalam satu , sehingga setiap pembacaan subtree adalah sebuahQuerypartisi-tunggal.SKadalah path lengkap dengan sebuah/di akhir pada folder. Garis miring di akhir itu disengaja — ia membuat sebuah folder terurut sebelum anak-anaknya sendiri dan menjagaroot/photos/tetap berbeda dari sebuah berkas saudara bernamaroot/photos.
Membaca sebuah subtree dalam satu query
Daftar semua yang ada di bawah root/photos/ — folder, subfolder, dan berkas, secara rekursif:
Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive = "DRIVE#a91"
:prefix = "root/photos/"
Itu mengembalikan root/photos/, root/photos/2026/, beach.jpg, dan sunset.jpg —
dalam urutan path, dalam satu pembacaan yang ditagih. Anda hanya membayar untuk item-item
di potongan itu, bukan seluruh drive.
Di DynoTable, Anda menjalankan query begins_with persis ini terhadap sort key path dan
folder plus turunannya kembali dalam urutan path — tanpa sintaks placeholder untuk ditulis
tangan.
Butuh KeyConditionExpression mentah (nama, nilai, dan begins_with) untuk kode Anda
sendiri? Bangun dan salin ia di
Pembuat Ekspresi DynamoDB.

Mendaftar satu level, bukan seluruh subtree
begins_with memberi Anda pembacaan rekursif. Untuk pendaftaran direktori yang
non-rekursif — anak-anak langsung dari root/photos/ dan tak ada yang lebih dalam —
simpan sebuah atribut depth dan tambahkan sebuah rentang sort key plus sebuah filter,
atau pisahkan path ke dalam sebuah GSI parent. Versi paling sederhana: simpan sebuah
atribut parent (root/photos/) dan sebuah GSI yang di-key padanya.
Intinya: sebuah sort key menjawab pertanyaan prefix dan rentang dengan murah.
"Anak langsung saja" adalah pertanyaan yang berbeda — modelkan ia secara eksplisit alih-alih
berharap sebuah FilterExpression membuatnya efisien. Sebuah filter berjalan setelah
pembacaan dan Anda membayar untuk setiap item yang ia buang.
Pilih delimiter dengan hati-hati
Delimiter adalah bagian dari kontrak data Anda. Dua aturan:
- Ia tak boleh pernah muncul di dalam sebuah segmen path. Jika nama berkas bisa berisi
/, maka/adalah delimiter yang salah — sebuah berkas bernamaa/btak bisa dibedakan dari sebuah folderayang menampungb. Pilih sebuah byte yang dicadangkan (beberapa tim menggunakan#atau sebuah karakter kontrol) dan larang ia di segmen. - Perhatikan urutan terurut di batas-batasnya.
/(0x2F) terurut sebelum digit dan huruf, yang biasanya adalah yang Anda inginkan untuk urutan pohon. Ubah delimiter-nya dan Anda mengubah pengurutannya — verifikasi ia terhadap data nyata.
Composite sort key vs. atribut sort terpisah
Composite sort key (root/photos/2026/x) | Sort key ID biasa + atribut parent | |
|---|---|---|
| Pembacaan subtree | Satu query begins_with | Query rekursif (N+1) atau jelajah GSI |
| Pengurutan | Urutan path, gratis | Harus menambah atribut sort eksplisit |
| Pindah / rename | Tulis ulang semua turunan | Perbarui satu pointer parent |
| Daftar anak langsung | Butuh atribut depth atau GSI | Alami (parent = x) |
Composite key menang saat pembacaan berbentuk-subtree dan pengurutan penting; model ID-datar menang saat pohonnya bermutasi terus-menerus. Kebanyakan hierarki yang berat-baca — pohon berkas, pohon kategori, bagan organisasi — condong ke composite.
Jebakan dan langkah selanjutnya
- Jangan menjejalkan key terlalu banyak. Semua yang Anda enkode adalah immutable dan terindeks hanya oleh prefix. Atribut yang Anda query menurut kesamaan adalah milik field-nya sendiri atau sebuah GSI, bukan dijejalkan ke dalam sort key.
- Sebuah sort key tak bisa melakukan
WHEREsembarang. Hanyabegins_with,between, dan perbandingan. Jika Anda mendapati diri menjangkau sebuahFilterExpression, Anda mungkin memodelkan key-nya salah — lihat Query vs. Scan. - Mendalami desain key ada di single-table design; untuk saat sebuah pembacaan subtree membutuhkan sebuah index alih-alih tabel dasar, lihat GSI vs. LSI.
Bangun kondisi key begins_with dengan
Expression Builder, lalu
unduh DynoTable untuk menjalankan query prefix ini terhadap tabel Anda sendiri
dan menyaksikan sebuah subtree kembali dalam urutan path. (Dan self-JOIN yang
Anda tinggalkan di SQL? SQL Workbench DynoTable tetap
menjalankannya saat Anda membutuhkannya.)


