Menyimpan gambar (atau file lain) di database versus di filesystem

Dalam menyimpan gambar (atau video, atau lampiran, atau file/objek lain) ada 2 pilihan: menyimpannya di database (relasional/SQL) langsung dalam kolom BLOB, atau hanya menyimpan ID/nama/path-nya saja di database sementara filenya sendiri disimpan di filesystem. Artikel ini mencoba membahas kekurangan dan kelebihan masing-masing cara.

Kepraktisan dalam pemrograman

Mereka yang pro-database menyebutkan, menyimpan di database lebih mudah/praktis dalam pemrograman, karena semuanya dilakukan lewat SQL. Tidak perlu ada operasi file lagi.

Sebetulnya ini relatif, bergantung pada apakah Anda lebih suka/terbiasa memrogram SQL atau memrogram filesystem.

Jika file-file diperoleh lewat upload browser (HTTP upload), umumnya menggunakan filesystem lebih mudah, karena hasil upload sudah dalam bentuk file, tinggal dipindahkan/disalin saja ke lokasi yang diinginkan. Sementara jika kita menggunakan database, sama-sama harus melakukan 1 langkah tambahan memindahkan/menyalin, yaitu meng-INSERT-nya ke database.

Untuk menampilkannya, jika kita menggunakan filesystem, dapat lebih sederhana/gampang. Kita tinggal menaruh file tersebut di lokasi yang dapat diakses via HTTP (misalnya, di bawah documenr root, di direktori images/). Maka selanjutnya webserver yang akan memberikannya pada klien. Sementara jika kita menggunakan database, maka kita setidaknya harus membuat skrip interface untuk memberikan file tersebut kepada klien (dan harus berurusan dengan HTTP resume dsb).

Keamanan

Masalah keamanan relatif, antara kedua cara memiliki keunggulan dan kelemahan.

Mereka yang pro-database mengatakan, jika menggunakan filesystem, maka kita tidak dapat membuat sistem permission yang “fine-grained” (mis: per user), dan harus membuka seluruh direktori image/ atau upload/ di mana berisi juga file-file milik user lain. Tentu saja ini tidak benar, karena dengan menggunakan filesystem pun kita dapat mengizinkan download file hanya lewat skrip kita dan tidak secara langsung (mis: download.php?file_id=2394 dan tidak langsung /files/2394.jpg, file-file kita taruh di direktori yang tidak dapat diakses lewat browser). Di skrip interface tersebut kita dapat melakukan pengecekan ekstra sesuai yang diinginkan, termasuk pengecekan hak setiap user.

Jika kita menggunakan filesystem, maka kita minimal perlu membuka 1 direktori agar dapat ditulisi oleh skrip. Ini berpotensi menjadi lubang keamanan jika Anda tidak melakukan setting dan pengecekan yang cukup. Misalnya, Anda perlu menjaga agar orang tidak dapat mengupload skrip ke direktori upload lalu mengeksekusinya via browser. Atau, menjaga agar user tidak dapat melihat listing direktori upload. Atau menjaga agar user tidak bisa menimpa file milik user lain. Atau agar nama filenya tidak mudah ditebak (Anda bisa menggunakan ID berupa MD5 hash misalnya).

Sementara jika menggunakan database, Anda perlu waspada terhadap SQL injection atau serangan-serangan lain terhadap database SQL Anda.

Dengan kata lain, menggunakan cara yang manapun memiliki risiko keamanannya tersendiri yang perlu Anda waspadai. Dalam pengamatan penulis, banyak programer PHP yang terbiasa hanya menggunakan MySQL sebagai penyimpanan data dan kurang berpengalaman dengan filesystem, apalagi filesystem Unix (karena mereka biasa melakukan pengembangan di Windows). Jika begini kasusnya, barangkali menyimpan di database lebih cocok karena risiko keamanannya lebih dikenali.

Kecepatan

Mereka yang pro-filesystem menyebutkan, menggunakan database akan lebih lambat.

Memang ada benarnya, dengan menggunakan database akan ada overhead yang lebih besar yaitu jalurnya harus melalui SQL, lalu ke database server, lalu baru ke file database (filesystem). Sementara jika menggunakan filesystem, maka jalurnya lebih pendek.

Namun soal kecepatan ini kini umumnya dalam kasus-kasus normal tidak terlalu berpengaruh karena lewat database pun kini sudah cukup cepat. Dan lagi Anda dapat menerapkan sistem caching agar file-file yang sering/baru saja diakses disimpan sementara di filesystem untuk jangka waktu tertentu agar jika diminta lagi maka dapat langsung diakses via filesystem.

Sebagian database juga memiliki fasilitas blob streaming agar BLOB yang besar sekali dapat langsung distream ke klien dan tidak harus diload semua dulu ke memori.

Untuk memastikan apakah lewat database cukup cepat, Anda dapat melakukan benchmarking sendiri pada aplikasi Anda.

Patokan garis besarnya adalah, tidak perlu mempermasalahkan soal kecepatan kecuali jika sudah perlu. Atau jika Anda merancang sesuatu yang skalanya amat besar (misalnya jutaan file, jutaan user, dsb).

Skalabilitas

Untuk masalah ini pun tiap cara punya metode masing-masing dan keduanya dapat di-scale up.

Dengan menyimpan di database, Anda tidak perlu pusing-pusing memikirkan layout filesystem, dan jika butuh dipecah-pecah ke server lain, kode program tidak perlu diubah-ubah, cukup string koneksi ke database saja yang diubah hostnya misalnya.

Namun dengan menyimpan di filesystem juga masalah skalabilitas dapat diatur. Untuk jumlah file yang sangat banyak, Anda dapat menggunakan filesystem yang terindeks (seperti reiserfs atau ext3+indeks) agar sebuah direktori dapat menampung jumlah file yang banyak (puluhan ribu ke atas) tanpa menjadi lambat. Atau Anda tinggal membuat layout sederhana misalnya tiga level (berdasarkan tanggal/tahun, huruf pertama dan kedua username, dsb). Lalu jika server untuk menyimpan file ingin dipisah, aplikasi tetap dapat menggunakan path lokal, karena tersedia cara untuk melakukan mounting filesystem remote seperti Samba, NFS, SSHFS, dsb.

Konsistensi data

Mereka yang pro-database menyebutkan, menyimpan file di database akan menjaga konsistensi data. Ini ada benarnya, karena jika file disimpan di filesystem, ada kemungkinan yang lebih besar bahwa file-file tersebut terhapus/terpindahkan di luar kendali aplikasi. Namun jika Anda cukup “tertib”, dan server/filesystem tempat menampung file-file Anda masih dalam kendali Anda, tentu Anda juga bisa mengatur/menjaga agar filesystem ini tetap tidak terganggu oleh aplikasi ketiga.

Kepraktisan dalam backup

Mereka yang pro-database menyebutkan, menyimpan file di database lebih sederhana dalam backup karena backupnya hanya satu saja.

Menurut penulis ini relatif, filesystem juga tentunya perlu dibackup (misalnya membackup kode aplikasi Anda, yang berada di filesystem!). Lagipula, backup dan restore database umumnya lebih lambat, jadi masuk akal jika kita menyimpan jumlah data yang banyak di filesystem karena backup dan restorenya lebih cepat.

Interoperabilitas

Menyimpan di filesystem dapat mempermudah akses aplikasi lain (yang tidak SQL-aware misalnya, contohnya skrip-skrip command line) terhadap file-file Anda. Misalnya, Anda dapat dengan mudah menggunakan skrip-skrip command line ImageMagick untuk membuat thumbnail terhadap file-file image/video Anda, atau melakukan full-text indexing, atau yang lainnya.

Namun tentunya bukan berarti jika menyimpan di database hal ini tidak dapat dilakukan.

Dan tentu Anda perlu berhati-hati agar penggunaan tool-tool seperti ini tidak merusak atau mengubah lokasi/nama file, karena jika tidak, data di database perlu diupdate agar keduanya tetap sinkron.

Full-text indexing

Untuk masalah ini, baik lewat filesystem maupun lewat database tersedia solusi untuk melakukan full-text indexing/searching terhadap file-file dokumen Anda. Menyimpan di database mungkin akan sedikit mempersederhana saat Anda melakukan query pencarian, tapi sebagian tool-tool full-text indexing/searching di luar database pun tidak kalah mudahnya untuk digunakan. Ini semua kembali ke kesukaan Anda.

Kesimpulan

Kedua cara memiliki kelemahan dan kelebihan masing-masing. Dalam kondisi tertentu satu cara mungkin lebih cocok atau lebih Anda sukai dibandingkan yang lain. Silakan memilihnya berdasarkan pertimbangan-pertimbangan yang telah dibahas. Berikut ini kesimpulan yang penulis buat:

Kedua sistem dapat bekerja baik dan dapat di-scale up, bergantung pada preferensi dan cara Anda mengaturnya.
Jika file-filenya amat besar dan banyak (misalnya, 30-50MB atau lebih per file, dan ada ratusan s.d. ribuan file) barangkali menyimpan di filesystem lebih cocok agar tidak terlalu memberati database Anda.
Bergantung pada sistem backup yang Anda punyai, membackup database saja mungkin lebih praktis bagi Anda. Tapi perlu diingat bahwa jika data file sangat besar, proses backup dan restore data akan menjadi lebih lambat, apalagi jika sistem backup/restore-nya menggunakan dump SQL yang mana termasuk yang paling lambat di antara sistem backup-restore database lainnya. Jika terjadi kerusakan dan harus melakukan restore dari database, proses restore bisa memakan waktu yang (jauh) lebih lama. Misalnya, merestore dari filesystem kecepatannya dapat mencapai 10GB/jam, namun jika dari dump SQL hanya 1GB/jam (misalnya).

Resita has written 705 articles