Menengah4 menit baca

Key Condition Expression DynamoDB

Sebuah key condition expression adalah KeyConditionExpression yang Anda lewatkan ke sebuah Query — satu-satunya bagian request yang dipakai DynamoDB untuk menemukan Item. Selebihnya (filter, projeksi) berjalan setelah pembacaan sudah dimeter.

Apa itu key condition expression di DynamoDB?

Key condition expression adalah KeyConditionExpression pada sebuah Query yang memberi tahu DynamoDB item mana yang akan dibaca. harus berupa kesetaraan (PK = :v); menerima satu operator rentang — =, <, <=, >, >=, BETWEEN, atau begins_with. Inilah yang menentukan apa yang dibaca dan ditagih, berbeda dengan filter.

  • Partition key harus berupa kesetaraan. PK = :v dan tak lebih — tanpa rentang, tanpa begins_with, tanpa IN. DynamoDB melakukan hash terhadapnya untuk menemukan satu partition.
  • Sort key mengambil operator rentang. =, <, <=, >, >=, BETWEEN, atau begins_with — di sinilah Anda mengiris sebuah item collection.
  • Ia bukan filter. Key condition memutuskan apa yang dibaca dan ditagih; sebuah FilterExpression hanya memangkas hasil setelah Anda membayar pembacaannya.
  • Sort key terurut-byte. Operator rentang membandingkan secara leksikografis, jadi cara Anda memformat string sort key adalah tenaga query Anda.

Mengapa partition key dikunci pada kesetaraan

DynamoDB menyimpan Item dengan melakukan hash terhadap partition key ke partition fisik. Sebuah hash memberi Anda satu lokasi, bukan rentang — jadi tak ada yang bisa di-scan melintasi.

Itulah mengapa PK > :v atau begins_with(PK, :v) ditolak mentah-mentah. Mesinnya tak bisa menjawab "semua partition yang keynya mulai dengan X" tanpa membaca seluruh tabel, yang persis Scan yang dibangun untuk dihindari.

Datang dari SQL, ini terasa terbalik: WHERE id LIKE 'order%' sepele di Postgres. Di DynamoDB partition key adalah alamat, bukan kolom yang dapat dicari.

Sort key adalah tempat tenaganya berada

Di dalam satu partition, Item disimpan terurut berdasarkan sort key. Pengurutan itulah yang dieksploitasi operator rentang — DynamoDB seek ke sebuah posisi dan membaca maju.

OperatorMembacaGunakan untuk
SK = :vSatu Item persisAnak tertentu berdasarkan keynya
SK < / <= / > / >= :vSatu irisan terbuka"Segalanya setelah titik ini"
SK BETWEEN :a AND :bRentang tertutup (inklusif)Jendela terbatas — rentang tanggal
begins_with(SK, :p)Irisan prefiksTipe atau hierarki di bawah PK

Tidak ada LIKE, tidak ada CONTAINS, tidak ada ENDS_WITH pada key. Pencocokan substring dan suffix tidak terurut-byte, jadi mereka akan memaksa pembacaan penuh — secara desain, API tak mengizinkannya. Itu hidup di FilterExpression, di mana Anda sudah membayar. (AWS: Key condition expressions)

Contoh nyata: pesan di aplikasi chat

Misalkan Anda membangun chat berbasis channel. Satu tabel, dipartisi per channel, diurut berdasarkan waktu pesan. Key schema asli:

  • Partition key ChannelRefCH#{channelId}
  • Sort key PostedAt — timestamp ISO-8601, MSG#2026-06-23T14:05:00Z

Prefiks MSG# menjaga baris pesan tetap dapat diurut dan berbeda dari tipe baris lain yang mungkin Anda kolokasikan di bawah channel yang sama (config tersemat, keanggotaan).

Muat pesan terbaru sebuah channel. Hanya partition key, terbaru lebih dulu:

KeyConditionExpression:  ChannelRef = :ch
ExpressionAttributeValues:  { ":ch": "CH#general" }
ScanIndexForward:  false

ScanIndexForward: false menjelajahi collection terurut secara terbalik — cara murah mendapat "paling baru lebih dulu" tanpa mengurutkan sisi-klien.

Hari tertentu dengan begins_with. Karena timestamp adalah sort key dan ia disimpan sebagai teks, prefiks tanggal adalah irisan yang bersih:

KeyConditionExpression  ChannelRef = :ch AND begins_with(PostedAt, :day)
:ch    "CH#general"
:day   "MSG#2026-06-23"

Itu membaca setiap pesan pada 2026-06-23 dan tak lebih — DynamoDB seek ke prefiks dan berhenti saat ia jatuh dari ujung. Ini hanya bekerja karena prefiksnya adalah left-anchor sejati dari string terurut-byte.

Jendela presisi dengan BETWEEN. Untuk "pesan selama jam 14:00", rentang inklusif mengalahkan prefiks:

KeyConditionExpression  ChannelRef = :ch AND PostedAt BETWEEN :lo AND :hi
:ch    "CH#general"
:lo    "MSG#2026-06-23T14:00:00Z"
:hi    "MSG#2026-06-23T14:59:59Z"

BETWEEN inklusif pada kedua batas, jadi pilih endpoint Anda dengan sengaja — off-by-one di sini diam-diam menjatuhkan atau menggandakan pesan tepi.

Anda bisa merakit dan menyalin salah satu expression ini, dengan peta ExpressionAttributeValues terisi untuk Anda, di DynamoDB expression builder — berguna untuk membenarkan sintaks begins_with dan BETWEEN sejak percobaan pertama.

Lihat di DynoTable

Jalankan key condition yang sama terhadap partition channel nyata dan saksikan consumed capacity diperbarui langsung, jadi Anda bisa memastikan Anda membaca sebuah irisan — bukan seluruh collection.

Jebakan: mengelirukan key condition dengan filter

Kesalahan mahalnya adalah meraih FilterExpression untuk melakukan tugas key.

KeyConditionExpression:  ChannelRef = :ch
FilterExpression:        begins_with(PostedAt, :day)

Ini tampak setara dengan key condition begins_with di atas dan mengembalikan baris yang sama — tetapi ia membaca seluruh partition channel dulu, lalu membuang segala yang di luar hari itu. Anda ditagih untuk pembacaan penuh.

Filter tak pernah mengurangi biaya pembacaan. Mereka berjalan setelah DynamoDB memeter Item-nya, footgun yang sama dengan Scan berfilter. Jika sebuah predikat bisa masuk ke key condition, di situlah tempatnya.

Solusinya di hulu: jika sebuah pola akses tak bisa diekspresikan sebagai satu kesetaraan PK plus rentang sort-key, itu adalah sinyal pemodelan. Bentuk ulang sort key, atau tambahkan index berkey untuk pola itu — lihat GSI vs LSI dan single-table design untuk cara menata key-nya.

Jebakan dan langkah berikutnya

  • Partition key selalu =. Tak pernah rentang. Jika Anda butuh rentang lintas partition, Anda telah melampaui satu Query.
  • Satu kondisi sort-key per query. Anda tak bisa meng-AND dua predikat sort-key; pilih BETWEEN atau begins_with, bukan keduanya.
  • Reserved word butuh alias. Key bernama Timestamp atau Name harus memakai ExpressionAttributeNames (#ts), atau query error. (AWS: reserved words)
  • BETWEEN inklusif. Kedua endpoint dicocokkan — rancang batas Anda sesuai itu.

Draf key condition Anda di expression builder, lalu coba DynoTable untuk menjalankannya terhadap tabel Anda sendiri dan menyaksikan kapasitas yang benar-benar mereka konsumsi.

Diperbarui