Projection expression DynamoDB
Projection expression adalah SELECT col1, col2 DynamoDB: daftar nama
dipisahkan koma yang memberitahu GetItem, Query,
atau Scan untuk mengembalikan hanya atribut itu alih-alih seluruh item.
Apakah projection expression DynamoDB mengurangi biaya baca?
Tidak. ProjectionExpression memangkas payload respons, bukan kapasitas baca
yang ditagih. DynamoDB membaca item penuh dari storage, mengukur
pada ukuran on-disk-nya, lalu menjatuhkan atribut yang
tidak Anda namai di jalan keluar. Untuk benar-benar memotong biaya baca, pakai
covering sebagai gantinya.
- Ia memangkas payload, bukan biaya baca. DynamoDB membaca (dan menagih)
item penuh dari storage, lalu menjatuhkan atribut yang tidak Anda namai di
jalan keluar.
ProjectionExpressionadalah optimasi jaringan, bukan kapasitas. - Itulah cara Anda mengambil subset publik. Namai sedikit atribut yang boleh dilihat pemanggil; sisanya tidak pernah meninggalkan tabel.
- Pakai placeholder
#nameuntuk apa pun yang mungkin reserved. Nama atribut polos di expression bertabrakan dengan ~570 reserved word DynamoDB dan gagal request. - Untuk penghematan baca nyata, pakai covering index. yang memproyeksikan hanya kolom yang Anda butuhkan dibaca pada ukuran (lebih kecil) sendiri.
Apa yang sebenarnya dihemat
Datang dari SQL, Anda menganggap SELECT a, b men-scan lebih sedikit daripada
SELECT *. Di DynamoDB intuisi itu salah.
Capacity unit untuk baca dihitung dari
ukuran item di disk, dibulatkan ke 4 KB berikutnya — sebelum proyeksi
diterapkan. AWS eksplisit: ProjectionExpression tidak mengubah kapasitas baca
yang dikonsumsi request.1
Jadi proyeksi menghemat dua hal, keduanya nyata tetapi keduanya di hilir baca:
- Byte di wire. Item 6 KB yang dikembalikan sebagai dua atribut kecil adalah
respons kecil. Pada
Queryyang mengembalikan ratusan item, itu cepat menumpuk. - Kerja sisi klien. Lebih sedikit untuk di-deserialize, lebih sedikit di memori, lebih sedikit untuk bocor ke log atau respons API secara tidak sengaja.
Apa yang tidak dihemat adalah RCU. Itulah jebakannya: orang menjangkau proyeksi untuk memotong tagihan, tidak melihat perubahan, dan menyimpulkan DynamoDB rusak. Tidak — Anda mengukur tuas yang salah.
Project profil pengguna publik
Katakan Anda menjalankan direktori pengguna. Tiap profil adalah satu item, di-key agar Anda bisa mengambil orang by handle:
PK = "PROFILE#ada" (partition key)
SK = "PROFILE#ada" (sort key — single-item collection)
Itemnya gemuk. Ia membawa wajah publik akun plus tumpukan atribut privat dan operasional:
{
"PK": "PROFILE#ada",
"SK": "PROFILE#ada",
"displayName": "Ada L.",
"avatarUrl": "https://cdn.example.com/u/ada.png",
"bio": "Builds things.",
"emailAddress": "ada@example.com",
"passwordResetToken": "…",
"billingCustomerId": "cus_…",
"lastLoginIp": "…",
"internalRiskScore": 0.02
}Kartu profil publik butuh tiga field. Mengambil seluruh item berarti
emailAddress, lastLoginIp, dan internalRiskScore pergi ke konteks yang
tidak boleh melihatnya. Namai hanya subset publik:
GetItem PK = "PROFILE#ada" SK = "PROFILE#ada"
ProjectionExpression: displayName, avatarUrl, bio
Respons membawa tiga atribut. Yang privat tetap di tabel — bukan difilter app Anda setelah tiba, tetapi tidak pernah di-serialize ke respons sama sekali. Itulah kemenangan keamanan, dan yang sulit di-undo setelah secret sudah menyeberangi batas.
Anda bisa menyusun dan menyalin request exact ini — name, placeholder, dan
panggilan SDK — di
DynamoDB Expression Builder, yang
mengeluarkan map ProjectionExpression dan ExpressionAttributeNames untuk
Anda.
Tambah atau hapus field di preset di bawah untuk menyaksikan
ProjectionExpression berubah — hanya atribut yang didaftar yang kembali:
Escape reserved word dengan placeholder #
Proyeksi bersih meledak pada reserved word. DynamoDB mereservasi daftar panjang
kata — name, status, comment, size, timestamp, dan ratusan lagi.2
Jika atribut yang Anda project adalah salah satunya, nama mentah di expression
ditolak.
Misalkan profil juga punya atribut status ("active", "suspended"). Ini
gagal:
ProjectionExpression displayName, status
status reserved. Perbaikannya adalah expression attribute name —
placeholder berawalan # yang dipetakan ke nama nyata:
ProjectionExpression displayName, #s
ExpressionAttributeNames { "#s": "status" }
Mekanisme yang sama menjangkau atribut nested. Untuk menarik satu field dari map, atau satu elemen list, pakai sintaks document-path — dan placeholder setiap segmen, karena mana pun bisa reserved:
ProjectionExpression #addr.#city, tags[0]
ExpressionAttributeNames { "#addr": "address", "#city": "city" }
Aturan praktis: placeholder semuanya. Anda tidak pernah harus mengingat mana
dari ~570 reserved word yang Anda injak, dan expression dibaca sama bagaimanapun.
Dan jika Anda lebih suka tahu nama mana yang benar-benar masalah, tempel ke
reserved-words checker — ia menandai
tabrakan dan mengeluarkan map alias ExpressionAttributeNames.
Kapan covering index mengalahkan proyeksi
Jika Anda benar-benar perlu memotong biaya baca — bukan sekadar payload — tuasnya
adalah Global Secondary Index yang memproyeksikan hanya atribut yang Anda
baca. GSI adalah salinan data terpisah; Anda memilih KEYS_ONLY, INCLUDE, atau
ALL untuk proyeksinya.3 Indeks KEYS_ONLY atau INCLUDE sempit
secara fisik lebih kecil per item, jadi Query terhadapnya diukur pada ukuran
lebih kecil itu.
Itulah covering index: query dijawab sepenuhnya dari indeks, tanpa trip kembali ke tabel dasar. Pakai saat pattern baca panas hanya pernah butuh sedikit atribut dari item besar.
ProjectionExpression | Covering GSI | |
|---|---|---|
| Potong payload | Ya | Ya |
| Potong biaya baca | Tidak | Ya — baca pada ukuran indeks |
| Storage ekstra | Tidak ada | Salinan kedua field yang diproyeksikan |
| Biaya tulis ekstra | Tidak ada | Write menyebar ke indeks |
| Terbaik untuk | Menyembunyikan field privat; kemenangan kecil | Baca panas sedikit field dari item besar |
Indeks menelan storage dan kapasitas tulis untuk menghemat kapasitas baca.
Sebanding untuk baca sering irisan tipis dari item berat; tidak sebanding untuk
mengurangi GetItem sekali. Lihat GSI vs LSI untuk
memilih tipe indeks, dan
saat baca GSI bisa basi sebelum Anda
menaruhnya di hot path.
Jebakan dan langkah selanjutnya
- Jangan harapkan tagihan lebih kecil. Proyeksi saja tidak pernah mengubah RCU. Jika angkanya tidak bergerak, itu perilaku terdokumentasi, bukan bug.
- Placeholder reserved word.
nameataustatustelanjang di expression gagal request —#-map. - Selalu sertakan atribut key — mereka menambah payload diabaikan dan membiarkan Anda memaginasi atau re-fetch item.
- Jangkau covering index hanya saat pattern panas membaca sedikit field dari item besar; timbang biaya tulis/storage dulu.
Bangun ProjectionExpression dan map attribute-name-nya di
Expression Builder, dan
coba DynoTable untuk menjalankan proyeksi ini terhadap tabel Anda
sendiri dan menyaksikan respons menyusut.
- Panduan Pengembang AWS DynamoDB, Using projection expressions in DynamoDB — kapasitas baca dihitung dari ukuran item sebelum
ProjectionExpressionapa pun diterapkan. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html ↩ - Panduan Pengembang AWS DynamoDB, Reserved Words in DynamoDB. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html ↩
- Panduan Pengembang AWS DynamoDB, Attribute Projections (
KEYS_ONLY/INCLUDE/ALL). https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html ↩