Hash

Hash sebagai penyimpanan seperti objek: operasi field, HINCRBY, dan kapan hash lebih tepat daripada string.

Daftar isi

Hash menyimpan sekumpulan pasangan field dan nilai pada satu key, sehingga satu objek data dapat tersimpan sebagai satu entri Redis tanpa perlu disusun menjadi string JSON. Field adalah nama anggota di dalam hash, misalnya nama atau prodi, dan setiap field menyimpan satu nilai string. Topik ini membahas operasi field pada hash, yaitu menulis dengan HSET, membaca dengan HGET, HMGET, dan HGETALL, memeriksa serta menghapus dengan HEXISTS, HSETNX, dan HDEL, menelusuri struktur dengan HLEN, HKEYS, dan HVALS, dan menghitung angka per field dengan HINCRBY. Di bagian akhir, hash dibandingkan dengan string JSON untuk memperjelas kapan salah satunya lebih tepat. Seluruh perintah dijalankan pada redis-cli dengan contoh profil mahasiswa dan koin poin.

Menyimpan field dengan HSET#

Hash adalah tipe data Redis yang memetakan nama field ke nilai di dalam satu key, sehingga strukturnya mirip objek pada bahasa pemrograman atau satu baris tabel basis data. Key hash mengikuti konvensi penamaan yang sama dengan key lain, misalnya profil:mahasiswa-1 untuk data satu mahasiswa. Jumlah field pada satu hash dapat bertambah kapan pun dibutuhkan, dan penambahan field baru tidak menyentuh field lain. HSET menulis satu atau beberapa pasangan field sekaligus dan mengembalikan jumlah field yang benar-benar baru, sedangkan penulisan pada field yang sudah ada hanya menimpa nilainya.

Diagram berikut memperlihatkan struktur tersebut, yaitu key profil:mahasiswa-1 yang memuat tiga pasangan field dan nilai.

keyprofil:mahasiswa-1fieldnilainamaCitraprodiFisikaangkatan2024
Satu key hash memuat pasangan field dan nilai

Perintah berikut membuat hash dengan tiga field dalam satu HSET, membaca satu field dengan HGET, lalu membaca field email yang belum tersimpan. Balasan pertama berupa 3 karena ketiga field semuanya baru, sedangkan HGET pada field yang tidak ada mengembalikan baris kosong dan bukan pesan error. Balasan kosong seperti itu wajar dalam redis-cli, sehingga aplikasi dapat memperlakukan field yang belum ada sebagai nilai default tanpa menambah alur penanganan error.

bash Menyimpan dan membaca field profil
# menghapus key contoh agar kondisi awal selalu sama
redis-cli del profil:mahasiswa-1 >/dev/null
# menyimpan tiga field dalam satu perintah HSET
redis-cli hset profil:mahasiswa-1 nama "Citra" prodi "Fisika" angkatan 2024
# membaca satu field
redis-cli hget profil:mahasiswa-1 nama
# membaca field yang belum tersimpan
redis-cli hget profil:mahasiswa-1 email
text Keluaran
3
Citra

Membaca satu, beberapa, atau seluruh field#

HGET membaca satu field, HMGET membaca beberapa field dalam satu permintaan, dan HGETALL mengembalikan seluruh isi hash. Balasan HMGET berupa satu baris untuk setiap field yang diminta, dan field yang tidak ada dilaporkan sebagai baris kosong. Balasan HGETALL berupa deretan bergantian antara nama field dan nilainya, sehingga jumlah barisnya selalu genap. HLEN melengkapi ketiganya dengan menghitung jumlah field tanpa membaca isinya.

bash Membaca sebagian dan seluruh field
# menyiapkan ulang key contoh
redis-cli del profil:mahasiswa-1 >/dev/null
redis-cli hset profil:mahasiswa-1 nama "Citra" prodi "Fisika" angkatan 2024
# membaca dua field sekaligus ditambah satu field yang belum ada
redis-cli hmget profil:mahasiswa-1 nama prodi email
# menampilkan seluruh pasangan field dan nilai
redis-cli hgetall profil:mahasiswa-1
# menghitung jumlah field
redis-cli hlen profil:mahasiswa-1
text Keluaran
3
Citra
Fisika

nama
Citra
prodi
Fisika
angkatan
2024
3

Pada keluaran tersebut, HMGET mengembalikan tiga baris sesuai banyaknya field yang diminta, dan baris ketiganya kosong karena email belum ada. HGETALL mengembalikan enam baris karena tiga pasangan disajikan bergantian, sedangkan HLEN mengembalikan 3 sesuai jumlah field yang baru ditulis.

Memeriksa, menambah bersyarat, dan menghapus field#

HEXISTS memeriksa keberadaan sebuah field dan mengembalikan 1 apabila field itu ada atau 0 apabila tidak. HSETNX menambah field hanya apabila field tersebut belum ada, singkatan dari hash set if not exists, dan mempertahankan nilai lama apabila field sudah ada. HDEL menghapus satu atau beberapa field sekaligus dan mengembalikan jumlah field yang benar-benar terhapus. Ketiganya memungkinkan pengelolaan field dilakukan secara selektif tanpa perlu membaca isi hash terlebih dahulu.

bash Memeriksa, menambah bersyarat, dan menghapus field
# menyiapkan ulang key contoh
redis-cli del profil:mahasiswa-1 >/dev/null
redis-cli hset profil:mahasiswa-1 nama "Citra" prodi "Fisika" angkatan 2024
# memeriksa keberadaan field
redis-cli hexists profil:mahasiswa-1 prodi
redis-cli hexists profil:mahasiswa-1 email
# menambah field hanya bila belum ada
redis-cli hsetnx profil:mahasiswa-1 email "[email protected]"
redis-cli hsetnx profil:mahasiswa-1 email "[email protected]"
# menghapus field angkatan
redis-cli hdel profil:mahasiswa-1 angkatan
# menampilkan sisa field
redis-cli hgetall profil:mahasiswa-1
text Keluaran
3
1
0
1
0
1
nama
Citra
prodi
Fisika
email
[email protected]

Pada keluaran tersebut, HSETNX pertama mengembalikan 1 karena email belum ada, sedangkan pemanggilan kedua mengembalikan 0 dan nilai lama tetap dipertahankan. HDEL mengembalikan 1 karena field angkatan memang ada, dan HGETALL sesudahnya hanya menampilkan tiga field yang tersisa. Apabila HDEL menghapus field terakhir pada sebuah hash, key tersebut ikut terhapus karena Redis tidak menyimpan hash kosong. Perilakunya berbeda dari string, yang tetap ada meskipun nilainya kosong, sehingga penghapusannya memerlukan DEL secara eksplisit.

Penghitung per field dengan HINCRBY#

Field hash juga menjadi tempat yang tepat untuk angka yang berubah, misalnya saldo koin poin seorang mahasiswa. HINCRBY menambah nilai sebuah field sebesar argumen yang diberikan dan mengembalikan nilai setelah penambahan, sedangkan argumen negatif mengurangi nilainya. Apabila field belum ada, HINCRBY memperlakukan nilainya sebagai 0 sebelum menambah. Agar keluaran contoh tetap sama pada setiap eksekusi, nilai awal disimpan terlebih dahulu melalui HSET.

bash Menambah dan mengurangi koin poin
# menyiapkan ulang hash koin poin
redis-cli del profil:mahasiswa-1 >/dev/null
# nilai awal disimpan melalui HSET agar hasil HINCRBY selalu sama
redis-cli hset profil:mahasiswa-1 nama "Citra" poin 50
# menambah 20 koin
redis-cli hincrby profil:mahasiswa-1 poin 20
# mengurangi 5 koin
redis-cli hincrby profil:mahasiswa-1 poin -5
# membaca saldo terakhir
redis-cli hget profil:mahasiswa-1 poin
text Keluaran
2
70
65
65

Perhitungan seluruhnya dilakukan oleh server dalam satu langkah, sehingga tidak ada jeda antara membaca saldo dan menuliskannya. Jeda semacam itu pada pola HGET lalu HSET dapat membuat dua proses yang membaca saldo yang sama saling menimpa hasil hitungannya, dan keadaan itulah yang dihindarkan oleh HINCRBY.

Satu key untuk satu objek#

Penyimpanan ala objek pada hash biasanya menyandingkan satu key dengan satu objek. Prefiks profil menandai kelompok data, sedangkan akhiran mahasiswa-1 dan mahasiswa-2 membedakan objeknya, sehingga pola penamaan mudah dibaca dan mudah dipindai. Dua key tidak saling memengaruhi, dan field pada masing-masing key dapat berbeda bila datanya memang berbeda. HKEYS dan HVALS membantu menelusuri hash yang fieldnya belum diketahui, yaitu HKEYS menampilkan daftar nama field tanpa nilai, sedangkan HVALS menampilkan daftar nilai tanpa nama field.

bash Menelusuri field pada dua profil
# menyiapkan dua profil mahasiswa
redis-cli del profil:mahasiswa-1 >/dev/null
redis-cli del profil:mahasiswa-2 >/dev/null
redis-cli hset profil:mahasiswa-1 nama "Citra" prodi "Fisika" angkatan 2024
redis-cli hset profil:mahasiswa-2 nama "Budi" prodi "Informatika" angkatan 2023
# menampilkan daftar nama field pada key pertama
redis-cli hkeys profil:mahasiswa-1
# menampilkan daftar nilai pada key kedua
redis-cli hvals profil:mahasiswa-2
text Keluaran
3
3
nama
prodi
angkatan
Budi
Informatika
2023

Balasan HSET pada kedua key sama-sama 3 karena masing-masing key semula kosong. HKEYS mengembalikan tiga nama field yang sama untuk kedua profil karena keduanya menggunakan struktur field yang sama, sedangkan HVALS mengembalikan nilai profil:mahasiswa-2 sesuai urutan penyisipannya. Apabila satu profil memerlukan field tambahan, field itu cukup ditambahkan pada key tersebut tanpa mengubah key lain.

Kapan hash lebih tepat daripada string JSON#

String JSON adalah pesaing alami hash karena objek juga dapat disimpan sebagai satu nilai string pada satu key. Memperbarui satu field pada string JSON menuntut aplikasi membaca seluruh nilai, mengurainya, mengubah bagian yang dimaksud, lalu menulis ulang semuanya. Hash menyediakan jalan yang lebih langsung karena setiap field dapat dibaca dan ditulis secara terpisah. Perbandingan berikut memperlihatkan pembaruan field prodi pada kedua pendekatan.

bash Memperbarui satu field pada hash dan pada string JSON
# menyiapkan ulang hash dan string JSON yang dibandingkan
redis-cli del profil:mahasiswa-1 >/dev/null
redis-cli del profil:json-1 >/dev/null
# hash: satu field diperbarui dengan satu perintah
redis-cli hset profil:mahasiswa-1 nama "Citra" prodi "Fisika"
redis-cli hset profil:mahasiswa-1 prodi "Kimia"
# string JSON: seluruh nilai ditulis ulang untuk satu perubahan
redis-cli set profil:json-1 '{"nama":"Citra","prodi":"Fisika"}'
redis-cli set profil:json-1 '{"nama":"Citra","prodi":"Kimia"}'
text Keluaran
2
0
OK
OK

Pada hash, pembaruan prodi hanya memerlukan satu HSET dan balasannya 0 karena tidak ada field baru yang dibuat. Pada string JSON, Redis tidak memahami isi JSON sehingga aplikasi harus mengurainya, dan seluruh nilai harus ditulis ulang walaupun yang berubah hanya satu bagian. Pembaruan per field juga menghemat pertukaran data karena hanya field yang disentuh yang dibaca atau ditulis.

Keterbatasan hash terletak pada ketiadaan tipe bertingkat, yakni nilai field selalu berupa string dan tidak dapat berisi hash atau list lain. Struktur bertingkat tetap memerlukan serialisasi, misalnya menjadi JSON, dan pada kebutuhan semacam itu string JSON menjadi pilihan yang lebih alami. Sebagai kaidah praktis, hash lebih tepat bila pembaruan per field sering terjadi, sedangkan string JSON lebih tepat bila objeknya bertingkat atau selalu dibaca dan ditulis sebagai satu kesatuan.

Kesalahan umum#

Kesalahan yang paling lazim adalah memanggil HINCRBY pada field yang nilainya bukan angka. Redis menafsirkan nilai field sebagai bilangan bulat ketika perintah penghitung dipanggil, sehingga field nama yang berisi teks memicu error. Perbaikannya adalah menyimpan angka pada field yang dihitung dan tidak menyentuh field teks dengan perintah tersebut.

bash Kesalahan: HINCRBY pada field yang bukan angka
# menyiapkan ulang hash contoh
redis-cli del profil:mahasiswa-1 >/dev/null
# field nama berisi teks dan poin berisi angka
redis-cli hset profil:mahasiswa-1 nama "Citra" poin 50
# HINCRBY menolak field yang nilainya bukan angka
redis-cli hincrby profil:mahasiswa-1 nama 1
# HINCRBY tetap berjalan pada field yang benar
redis-cli hincrby profil:mahasiswa-1 poin 10
text Keluaran
2
ERR hash value is not an integer

60

Kesalahan kedua adalah menganggap HSET selalu menambah field. HSET menimpa nilai field yang sudah ada tanpa pesan apa pun, sehingga balasannya dapat 0 padahal penulisan berhasil. Apabila yang diinginkan penambahan bersyarat, gunakan HSETNX, dan apabila keberadaan field perlu dipastikan sebelum menulis, gunakan HEXISTS.

Ringkasan#

  • HSET menulis pasangan field dan nilai pada satu key dan mengembalikan jumlah field yang benar-benar baru, sedangkan HGET, HMGET, dan HGETALL membaca satu, beberapa, atau seluruh field.
  • HLEN, HKEYS, dan HVALS menelusuri struktur hash, sedangkan HEXISTS, HSETNX, dan HDEL memeriksa, menambah bersyarat, serta menghapus field secara selektif.
  • HINCRBY menambah nilai angka pada field secara atomik di server, sehingga lebih aman daripada pola HGET lalu HSET untuk pembaruan yang berlomba.
  • Hash lebih tepat daripada string JSON ketika pembaruan per field sering terjadi, tetapi nilai field selalu berupa string sehingga struktur bertingkat tetap memerlukan serialisasi.

Referensi#