Mengapa graf

Relasi sebagai data kelas satu dan titik di mana SQL serta dokumen mulai kesulitan menjawab pertanyaan keberhubungan.

Daftar isi

Topik ini menjelaskan mengapa basis data graf ada, dengan relasi sebagai data kelas satu (first-class data) di pusat pembahasannya. Lingkupnya mencakup perbedaan cara relasi tersimpan pada model graf, relasional, dan dokumen, dilanjutkan dengan titik di mana pertanyaan keberhubungan seperti “teman dari teman” menjadi mahal pada dua model terakhir. Satu kueri Cypher pada data contoh dijalankan untuk menunjukkan mekanismenya, dan pembahasan ditutup dengan perbandingan yang jujur beserta tabel ringkasnya.

Relasi sebagai data kelas satu#

Data kelas satu berarti sebuah hal diperlakukan sebagai bagian utama model data, bukan hasil turunan dari hal lain. Pada model graf, relasi memenuhi definisi tersebut: setiap relasi memiliki tipe dan arah, menghubungkan dua node tertentu, serta boleh membawa properti sendiri. Node adalah titik entitas di dalam graf, misalnya seorang siswa atau sebuah kota, sedangkan relasi adalah koneksi bernama di antara dua node. Neo4j menyimpan setiap relasi sebagai rekaman fisik yang memuat penunjuk langsung menuju kedua node ujungnya, dan pendekatan penyimpanan ini dikenal sebagai index-free adjacency. Penunjuk yang tersimpan membuat langkah berikutnya dalam penelusuran (traversal) tidak memerlukan pencarian indeks.

Model penyimpanan Neo4j disebut property graph, dan anatomi lengkapnya dibahas pada modul model property graph. Basis data relasional menyimpan entitas di dalam tabel, sedangkan hubungan antar barisnya tidak tersimpan sebagai data. Kunci asing (foreign key) berlaku sebagai syarat yang diperiksa pada saat penulisan, bukan penunjuk yang dibaca pada saat kueri, sehingga hubungan hanya terbentuk kembali ketika dua tabel digabungkan dan nilai kolomnya cocok. Basis data dokumen menempatkan data pada dokumen mandiri: hubungan yang muat di dalam satu dokumen ikut tertanam di dalamnya, sedangkan hubungan menuju dokumen lain hanya berupa nilai pengenal. Pada kedua model itu, keberhubungan adalah hasil perhitungan pada saat kueri, sedangkan pada model graf keberhubungan adalah bagian dari data yang tersimpan.

Pertanyaan keberhubungan pada graf contoh#

Data contoh pada topik ini adalah jaringan sosial kecil yang berisi tiga siswa bernama Danu, Eka, dan Fitri. Setiap siswa disimpan sebagai node berlabel :Siswa dengan properti nama, sedangkan relasi bertipe :SAHABAT menghubungkan Danu dengan Eka, kemudian Eka dengan Fitri. Seluruh node dan relasi contoh dibuat dengan pernyataan MERGE yang idempoten, sehingga pemuatan berulang tidak menggandakan data. Rantai tiga node ini cukup untuk menguji pertanyaan keberhubungan yang khas, yaitu nama sahabat Danu pada satu lompatan (hop) dan nama sahabat dari sahabat Danu pada dua lompatan. Satu lompatan berarti melintasi satu relasi dari node pangkal, sehingga dua lompatan berarti melintasi dua relasi yang bersambung.

Kueri Cypher berikut mencari node yang dicapai dari Danu melalui dua relasi :SAHABAT berturut-turut.

cypher
MATCH (:Siswa {nama: "Danu"})-[:SAHABAT]->()-[:SAHABAT]->(jauh)
RETURN jauh.nama AS dua_lompatan
ORDER BY dua_lompatan;
text Keluaran
dua_lompatan
"Fitri"

Keluaran memuat satu nama, Fitri, karena satu-satunya jalur dua lompatan dari Danu melintasi Eka, sedangkan kueri satu lompatan yang setara mengembalikan Eka. Biaya kueri semacam ini sebanding dengan jumlah relasi yang disentuh: mesin graf memulai penelusuran dari node Danu, membaca penunjuk relasi :SAHABAT milik node itu, lalu mengulangi hal yang sama pada node yang dicapai. Node dan relasi di luar jalur yang disentuh tidak ikut diperiksa, sehingga pertambahan ukuran graf tidak serta-merta memperbesar biaya kuerinya.

Biaya yang sama pada SQL dan basis data dokumen#

Pertanyaan keberhubungan yang sama dijawab basis data relasional dengan self join, yaitu penggabungan tabel keberhubungan dengan dirinya sendiri, sebanyak jumlah lompatan yang ditanyakan. Satu lompatan memerlukan satu penggabungan, dua lompatan memerlukan dua penggabungan yang dirangkai, dan setiap lompatan tambahan menambah satu penggabungan lagi atas tabel yang sama. Penggabungan mencocokkan nilai kolom baris demi baris, sehingga biayanya mengikuti ukuran tabel keberhubungan, bukan panjang jalur yang benar-benar dicari. Kedalaman yang baru diketahui pada saat kueri berjalan memaksa penggunaan CTE rekursif (recursive common table expression), yaitu fasilitas SQL yang mengulang penggabungan sampai tidak ada baris baru yang muncul.

Pada basis data dokumen, hubungan antar dokumen yang tidak tertanam tersimpan sebagai nilai pengenal, sehingga keberhubungan disusun kembali pada saat kueri. Operator $lookup yang berjalan pada alur agregasi (aggregation pipeline) MongoDB mengambil dokumen yang dirujuk, dan setiap lompatan tambahan menambah satu tahap $lookup lagi. Penyusunan ulang itu berulang pada setiap eksekusi kueri karena tidak ada penunjuk fisik yang tersimpan antara dokumen yang terhubung. Kedua model tetap mampu menjawab pertanyaan keberhubungan, tetapi biayanya melekat pada cara hubungan direkonstruksi, bukan pada jumlah data yang dilintasi.

Perbandingan yang jujur#

Perbedaan karakter biaya tersebut tidak menjadikan graf unggul pada segala pekerjaan. Rekap dan agregasi atas himpunan baris yang homogen, misalnya statistik nilai ujian per kelas, tetap nyaman dikerjakan SQL karena bahasa itu memang dirancang untuk operasi himpunan. Pembacaan dokumen mandiri juga lebih murah pada basis data dokumen karena satu dokumen memuat seluruh isinya sekaligus. Graf justru paling bernilai pada pertanyaan keberhubungan, terutama apabila kedalaman lompatannya besar atau baru diketahui pada saat kueri berjalan, dan pada domain yang datanya semakin terhubung seiring waktu. Tabel berikut merangkum perbandingan tersebut.

KebutuhanModel yang paling nyamanAlasan
Relasi tersimpan sebagai data utuhgrafrelasi memiliki tipe, arah, dan penunjuk fisik antarnode
Kecocokan pola dua lompatan atau lebihgrafbiaya menelusuri sebanding bagian graf yang disentuh
Kedalaman lompatan baru diketahui saat kueri berjalangrafpola lompatan panjang variabel tersedia tanpa CTE rekursif
Rekap dan agregasi atas himpunan besarrelasionalSQL dirancang untuk operasi himpunan
Pembacaan dokumen mandiridokumensatu dokumen memuat data yang biasanya dibaca bersama

Tabel tersebut menyederhanakan keputusan nyata yang biasanya mempertimbangkan ekosistem alat, kebiasaan tim, dan bentuk data yang sudah ada. Banyak sistem menerapkan lebih dari satu model sekaligus: data operasional tetap berada pada basis data relasional atau dokumen, sedangkan salinannya yang diperlakukan sebagai graf dipelihara di Neo4j untuk kebutuhan penelusuran. Susunan dua model semacam ini memerlukan alur sinkronisasi antar sistem yang dirawat secara berkelanjutan. Apabila pertanyaan keberhubungan mendominasi kebutuhan aplikasi, model graf menjadi pilihan yang layak dipertimbangkan.

Ringkasan#

  • Relasi pada model graf adalah data kelas satu, yaitu bertipe, berarah, menghubungkan dua node tertentu, dan tersimpan sebagai penunjuk fisik yang dibaca pada saat kueri.
  • Pertanyaan keberhubungan dikerjakan dengan penelusuran yang mengikuti penunjuk tersebut, sehingga biayanya sebanding dengan bagian graf yang disentuh.
  • SQL menjawab pertanyaan yang sama dengan self join per lompatan atau CTE rekursif, sedangkan basis data dokumen menyusun ulang hubungan melalui $lookup pada setiap eksekusi.
  • Graf bukan pengganti model lain, karena agregasi himpunan besar tetap wilayah SQL dan pembacaan dokumen mandiri tetap wilayah basis data dokumen.

Referensi#