Set adalah kumpulan string yang tidak berurutan dan tidak memuat duplikat, sehingga satu nilai hanya tersimpan satu kali di dalam satu set. Topik ini membahas penambahan anggota dengan SADD, pemeriksaan keanggotaan dengan SISMEMBER, penghitungan jumlah anggota dengan SCARD, penampilan isi dengan SMEMBERS, serta operasi antar set berupa irisan dengan SINTER, gabungan dengan SUNION, dan selisih dengan SDIFF. Tinjauan kompleksitas setiap operasi himpunan melengkapi pembahasan perintahnya. Studi kasusnya adalah tag pada artikel dokumentasi bantuan dan daftar artikel yang dibaca siswa sebagai dasar rekomendasi sederhana.
Keanggotaan dan keunikan#
SADD menambahkan satu atau lebih anggota ke dalam set dan mengembalikan jumlah anggota yang benar-benar baru ditambahkan. Anggota yang sudah ada diabaikan tanpa error, itulah sebabnya penambahan ulang tag yang sama mengembalikan 0. Penambahan dan pemeriksaan keanggotaan berlangsung dengan biaya yang tetap untuk setiap anggota yang disentuh, sehingga pertanyaan sudah atau belum tetap cepat dijawab pada set berukuran besar.
SISMEMBER memeriksa satu anggota dan mengembalikan 1 atau 0, sementara SMISMEMBER memeriksa beberapa anggota sekaligus dan mengembalikan satu balasan untuk setiap anggota sesuai urutan pertanyaannya. SREM menghapus anggota dan mengembalikan jumlah yang terhapus, sedangkan SCARD menghitung jumlah seluruh anggota. Kombinasi ini menutup kebutuhan dasar tagging, yaitu menyimpan daftar tag per artikel tanpa mengkhawatirkan duplikasi. Pola yang sama berlaku pada daftar hadir, yaitu set per sesi pelatihan yang diisi nama peserta ketika kehadirannya dicatat, dengan SCARD sebagai jumlah hadir dan SISMEMBER sebagai pemeriksaan per nama. Pencatatan yang terpanggil dua kali untuk nama yang sama tidak mengubah isi setnya.
# menghapus set lama agar isi selalu mulai dari kosong
redis-cli del set:artikel:12:tag
# menambahkan tiga tag sekaligus
redis-cli sadd set:artikel:12:tag redis basis-data caching
# tag yang sama diabaikan
redis-cli sadd set:artikel:12:tag redis
# jumlah anggota setelah penambahan
redis-cli scard set:artikel:12:tag
# memeriksa satu anggota
redis-cli sismember set:artikel:12:tag caching
# memeriksa anggota yang tidak ada
redis-cli sismember set:artikel:12:tag grafik
# memeriksa dua anggota sekaligus
redis-cli smismember set:artikel:12:tag redis grafik
# menghapus satu tag
redis-cli srem set:artikel:12:tag caching
# jumlah anggota setelah penghapusan
redis-cli scard set:artikel:12:tag1
3
0
3
1
0
1
0
1
2Menampilkan isi dan jumlah anggota set#
SMEMBERS mengembalikan seluruh anggota sebuah set dalam satu perintah. Untuk keperluan rekomendasi, set yang digunakan berisi nomor artikel sehingga isinya mudah dibandingkan antar siswa. Pada contoh berikut, set set:dibaca:ali menyimpan nomor artikel yang dibaca Ali, dan SMEMBERS menampilkannya seluruhnya. Apabila isi set perlu diketahui tanpa menampilkan semuanya, SRANDMEMBER mengambil satu atau beberapa anggota secara acak, tetapi keluarannya berbeda pada setiap pemanggilan sehingga contoh pada jalur ini tidak mengeksekusinya.
# menghapus set lama
redis-cli del set:dibaca:ali
# Ali membaca tiga artikel bernomor 12, 13, dan 14
redis-cli sadd set:dibaca:ali 12 13 14
# menampilkan seluruh anggota
redis-cli smembers set:dibaca:ali
# jumlah artikel yang dibaca
redis-cli scard set:dibaca:ali1
3
12
13
14
3Bentuk penyimpanan internal set menyesuaikan isinya. Set kecil yang seluruh anggotanya bilangan bulat disimpan sebagai intset, yaitu array bilangan bulat yang terurut, sedangkan set yang lebih besar atau memuat string disimpan sebagai tabel hash. Perbedaan ini menjelaskan catatan di atas karena array yang terurut memang tercetak berurutan. SMEMBERS membaca seluruh anggota dengan biaya sebanding jumlah anggotanya, sehingga ukuran set perlu diperhatikan sebelum perintah ini dipanggil berulang-ulang.
Irisan, union, dan selisih#
Operasi antar set menyelesaikan banyak pertanyaan rekomendasi tanpa kode tambahan di sisi aplikasi. SINTER mengembalikan anggota yang ada di seluruh set yang dirujuk, dalam kasus ini artikel yang dibaca oleh dua siswa sekaligus sebagai kandidat rekomendasi bersama. SUNION menggabungkan seluruh anggota dari semua set yang dirujuk, sedangkan SDIFF mengembalikan anggota yang ada di set pertama tetapi tidak ada di set lain, sehingga arah argumen menentukan hasilnya. Varian SINTERSTORE, SUNIONSTORE, dan SDIFFSTORE menyimpan hasilnya ke key baru alih-alih mengembalikannya, berguna ketika hasil akan digunakan berulang kali.
# menghapus kedua set agar isi selalu sama
redis-cli del set:dibaca:ali set:dibaca:citra
# Citra membaca artikel 13, 14, dan 15
redis-cli sadd set:dibaca:ali 12 13 14
redis-cli sadd set:dibaca:citra 13 14 15
# artikel yang dibaca keduanya
redis-cli sinter set:dibaca:ali set:dibaca:citra
# seluruh artikel yang tersentuh
redis-cli sunion set:dibaca:ali set:dibaca:citra
# artikel yang dibaca Ali tetapi bukan Citra
redis-cli sdiff set:dibaca:ali set:dibaca:citra2
3
3
13
14
12
13
14
15
12Irisan mengembalikan 13 dan 14, gabungan mengembalikan 12 sampai 15, dan selisih mengembalikan 12 karena artikel itu hanya dibaca Ali.
Perbedaan SINTER dengan SINTERSTORE terletak pada tujuan hasilnya. SINTER mengirimkan hasil kepada klien pemanggil, sedangkan SINTERSTORE menyimpannya ke key tujuan dan mengembalikan jumlah anggota yang tersimpan. Key tujuan yang sudah ada ditimpa seutuhnya dalam satu langkah atomik, sehingga hasil yang dibaca berulang cukup dihitung sekali lalu disimpan. Pola ini cocok untuk daftar kandidat rekomendasi yang dihitung berkala dan dibaca oleh banyak proses lain.
Kompleksitas operasi himpunan#
Setiap operasi himpunan memiliki biaya yang dapat diperkirakan dari ukuran operandnya. SADD, SREM, SISMEMBER, dan SCARD bekerja dengan biaya tetap untuk setiap anggota yang disentuh, sehingga pemeriksaan keanggotaan tetap cepat pada set berjuta anggota. SMEMBERS, SUNION, dan SDIFF sebanding dengan jumlah anggota yang terlibat karena server harus menyusun seluruh balasannya. SINTER paling mahal di antara semuanya karena pada kasus terburuk setiap anggota set terkecil diperiksa terhadap set lainnya.
Perbedaan biaya ini berpengaruh karena Redis mengerjakan perintah secara berurutan. Satu irisan yang memakan waktu lama menunda perintah lain yang sedang menunggu, termasuk perintah singkat dari aplikasi lain. Perbedaannya baru terasa pada set berisi puluhan ribu anggota atau lebih, sedangkan dua set kecil tetap murah diproses. Pembatasan ukuran set yang dirujuk dan pemilihan waktu eksekusi bagi operasi berat menjaga responsivitas server. Prinsipnya sederhana, yaitu operasi yang menyentuh seluruh anggota diperlakukan sebagai operasi berat. Untuk pertanyaan keanggotaan tunggal, SISMEMBER hampir selalu lebih tepat daripada SMEMBERS yang dibaca lalu diperiksa kembali di sisi aplikasi.
Kesalahan umum#
Kesalahan pertama adalah menafsirkan balasan 0 dari SADD sebagai kegagalan. Balasan 0 berarti anggota sudah ada sebelumnya dan set tidak berubah, justru perilaku itulah yang menjamin keunikan anggota. Kesalahan kedua adalah terkecoh arah argumen SDIFF. Bentuk SDIFF a b mengembalikan isi a yang tidak ada di b, sedangkan SDIFF b a mengembalikan kebalikannya, sehingga urutan argumen wajib diperhatikan pada kueri rekomendasi. Kesalahan ketiga adalah mengandalkan urutan keluaran SMEMBERS untuk logika aplikasi. Set tidak berurutan menurut desain, sehingga urutan tampil dapat berubah antar versi data dan antar tipe penyimpanan internal. Apabila urutan itu penting, pindahkan data ke sorted set yang menyimpan skor per anggota.
Kesalahan keempat adalah menggunakan set untuk menghitung kejadian yang berulang. Set membuang duplikat pada saat penyimpanan, sehingga SCARD tidak bertambah meskipun anggota yang sama ditambahkan berkali-kali. Penghitungan kejadian seperti jumlah kali artikel dibaca lebih tepat ditangani penghitung pada string atau field hash, misalnya INCR pada string atau HINCRBY pada hash.
Ringkasan#
- SADD menjamin keunikan anggota dengan mengabaikan duplikat dan mengembalikan jumlah anggota yang benar-benar baru.
- SISMEMBER dan SMISMEMBER memeriksa keanggotaan tanpa membaca seluruh isi set.
- SINTER, SUNION, dan SDIFF menjawab pertanyaan irisan, gabungan, dan selisih langsung di server.
- Urutan anggota SMEMBERS tidak dijamin, sehingga kebutuhan terurut sebaiknya menggunakan sorted set.
Referensi#
- Sets — Redis — Dokumentasi tipe data set beserta contoh operasi himpunan.
- SADD — Redis — Dokumentasi perintah SADD beserta semantik balasan jumlah anggota baru.
- SINTER — Redis — Dokumentasi perintah SINTER untuk irisan antar set.