Apa tempat terbaik untuk menyimpan file biner yang terkait dengan data di database Anda? Seharusnya kamu:
- Simpan di database dengan gumpalan
- Simpan di sistem file dengan tautan di basis data
- Simpan di sistem file tetapi ganti nama menjadi hash dari konten dan simpan hash pada database
- Sesuatu yang tidak pernah saya pikirkan
Keuntungan dari (1) adalah (antara lain) bahwa keaslian transaksi dipertahankan. Biayanya adalah Anda mungkin secara dramatis meningkatkan persyaratan penyimpanan (dan streaming / cadangan terkait)
Tujuan dari (3) adalah untuk mempertahankan atomisitas sampai taraf tertentu - jika Anda dapat memastikan bahwa sistem file yang Anda tulis tidak memungkinkan file untuk diubah atau dihapus, dan selalu memiliki hash yang benar sebagai nama file. Idenya adalah untuk menulis file ke sistem file sebelum mengizinkan memasukkan / memperbarui referensi hash - jika transaksi ini gagal setelah sistem file menulis tetapi sebelum DML database, itu baik-baik saja karena sistem file 'berpura-pura' menjadi gudang semua kemungkinan file dan hash - tidak masalah jika ada beberapa file di sana yang tidak diarahkan (dan Anda dapat membersihkannya secara berkala jika Anda berhati-hati)
SUNTING:
Sepertinya beberapa RDBMS membahas hal ini dalam cara masing-masing - Saya tertarik untuk mengetahui bagaimana orang lain melakukannya - dan khususnya dalam solusi untuk postgres
sumber
Jawaban:
Simpan di database dengan gumpalan
Kerugiannya adalah membuat file database Anda cukup besar dan mungkin terlalu besar untuk dicadangkan dengan pengaturan yang ada. Keuntungannya adalah integritas dan atomitas.
Simpan di sistem file dengan tautan di basis data
Saya telah menemukan bencana yang sangat mengerikan dalam melakukan ini, dan saya takut orang-orang terus menyarankannya. Beberapa bencana termasuk:
C:\
semua jalan ke.doc
dan tidak semua versi NT mampu menangani jalur panjang.Simpan di sistem file tetapi ganti nama menjadi hash dari konten dan simpan hash pada database
Tempat terakhir saya bekerja melakukan ini berdasarkan penjelasan saya tentang skenario di atas melakukan ini. Mereka berpikir itu adalah kompromi antara ketidakmampuan organisasi untuk mendapatkan pengalaman dengan database besar (apa pun yang lebih besar dari sekitar 40G ditahbiskan menjadi "terlalu besar"), ketidakmampuan perusahaan untuk membeli hard drive besar, dan ketidakmampuan untuk membeli kembali yang lebih modern solusi, dan kebutuhan untuk menjauh dari risiko # 1 & # 3 yang saya identifikasi di atas.
Pendapat saya adalah bahwa menyimpan dalam DB sebagai gumpalan adalah solusi yang lebih baik dan lebih skalabel dalam skenario multi-server, terutama dengan masalah failover dan ketersediaan.
sumber
Nomor 1 untuk integritas data lengkap. Gunakan opsi lain jika Anda tidak peduli dengan kualitas data. Sesederhana itu.
Kebanyakan RDBMS memiliki optimisasi untuk menyimpan BLOB (misalnya filestream SQL Server)
sumber
Jika memilih oracle, lihat dbfs dan Secure Files.
File Aman mengatakan semuanya, jaga SEMUA data Anda aman dalam database. Ini diatur dalam lobs. File Aman adalah versi modern dari lobs, yang harus diaktifkan.
dbfs adalah sistem file dalam database. Anda dapat memasang serupa seperti sistem file jaringan, pada host Linux. Ini sangat kuat. Lihat blog Ini juga memiliki banyak opsi untuk menyesuaikan dengan kebutuhan spesifik Anda. Menjadi dba, diberi filesystem (berbasis di database, dipasang di Linux), saya membuat Oracle Database di atasnya tanpa masalah. (database, disimpan dalam ... database). Bukannya ini akan sangat berguna tetapi itu menunjukkan kekuatan.
Lebih banyak keuntungan adalah: ketersediaan, cadangan, pemulihan, semua membaca konsisten dengan data relasional lainnya.
Terkadang ukuran diberikan sebagai alasan untuk tidak menyimpan dokumen dalam database. Data itu mungkin harus dicadangkan dengan cara apa pun sehingga itu bukan alasan yang baik untuk tidak menyimpan dalam database. Terutama dalam situasi di mana dokumen lama dianggap hanya baca, mudah untuk membuat sebagian besar basis data hanya baca. Dalam hal itu, bagian-bagian dari basis data tidak lagi membutuhkan cadangan yang sering tinggi.
Referensi dalam tabel untuk sesuatu di luar database tidak aman. Ini dapat dimanipulasi, sulit untuk diperiksa dan dapat dengan mudah hilang. Bagaimana dengan transaksi? Basis data menawarkan solusi untuk semua masalah ini. Dengan Oracle DBFS, Anda dapat memberikan dokumen Anda ke aplikasi non basis data dan mereka bahkan tidak akan tahu mereka mencari-cari di dalam basis data.
Yang terakhir, kejutan besar, kinerja sistem file dbfs seringkali lebih baik daripada sistem file biasa. Ini benar terutama jika file lebih besar dari beberapa blok.
sumber
Saya pikir jawaban yang tepat di sini sangat tergantung pada aplikasi Anda, dan seberapa penting dokumen-dokumen itu.
Untuk sistem manajemen dokumen, atau sistem yang dapat memulihkan dokumen yang disimpan sangat penting (sehingga sebagian besar terkait dengan keuangan, SDM, atau CRM), menyimpan dokumen secara sejajar, atau menggunakan teknologi dokumen milik vendor DB favorit Anda sepertinya Right Thing To Do.
Namun, ada banyak aplikasi di mana saya percaya bahwa keputusan yang sebaliknya tepat.
Sistem Helpdesk dan sistem wiki-jenis adalah yang mana saya pikir itu membuat banyak akal untuk menjaga data keluar dari database. Saya percaya beberapa, seperti Jira, sebenarnya memberikan opsi untuk memilih apakah Anda ingin menyimpan dokumen inline atau tidak.
Untuk bisnis berukuran sedang, menyimpan dokumen untuk sistem tiket inline dapat berarti perbedaan antara cadangan terkompresi yang diukur dalam megabita, dan yang diukur dalam gigabita.
Saya pribadi lebih suka untuk membawa sistem tiket kembali online dalam beberapa menit dan bergulat dengan dokumen (umumnya kurang penting) selama beberapa jam, daripada meningkatkan "itu rusak dan CTO bernapas di leher saya" RTO dengan harus mengembalikan dan memutar ulang log dari cadangan yang jauh lebih besar.
Ada manfaat lain dari menjaga dokumen tetap terpisah.
Saya pikir kombinasi hibrida dari # 2 dan # 3 mungkin pintar. Simpan nama file asli, tetapi hitung dan simpan hash / checksum dokumen, sehingga Anda memiliki beberapa titik referensi yang akan membantu pemulihan jika seseorang memindahkan atau mengganti nama file tersebut.
Menyimpan file dengan nama file aslinya berarti bahwa aplikasi dapat benar-benar menariknya langsung dari sistem file dan mengirimkannya melalui kabel, atau dalam dunia klien yang tebal, bahkan mungkin mengarahkan pengguna langsung ke server file.
sumber
Jangan lakukan itu.
Sebenarnya tidak ada terbalik memiliki file yang disimpan dalam database.
Bukankah sudah terasa aneh dan mencurigakan saat Anda berpikir:
Lebih baik lagi, ucapkan dengan lantang.
Ke fakta:
Menggunakan database
" PROS " ... tetapi tidak cukup :
Saya benar-benar tidak ingin menjadi bias, tetapi saya pikir tidak ada lagi yang perlu ditambahkan. Pro tidak terlalu bagus jika Anda memikirkannya.
Jika saya lupa sesuatu komentar di bawah ini, sementara itu baca terus di bawah ini.
CONS:
Menggunakan sistem file
PROS:
CONS :
* Cetak halus
Saat ini kau bertanya pada dirimu sendiri, tunggu sebentar, maksudmu tidak ada kontra ?! Bagaimana bisa?
Kesalahan terbesar di sini adalah orang-orang mencoba mengencangkan sekrup dengan palu.
Alasan utama dan saya akan mengatakan satu-satunya alasan mengapa ini ditanyakan adalah karena tautan file .
Ini adalah masalah yang tidak ingin diselesaikan oleh database. Bahkan terdengar konyol jika Anda memikirkannya.
Ketika pada kenyataannya, secara logis aplikasi harus benar-benar bertugas menangani dan melayani tautan.
Sebuah solusi:
Ini juga akan mengabstraksi jalur asli, membuat aplikasi lebih portabel, dapat dipelihara dan memungkinkan untuk beralih ke semua jenis sistem file tanpa merusak apa pun.
Adapun cara mengimplementasikannya berada di luar cakupan jawaban ini, tetapi Anda dapat melihat contoh umum dalam bahasa web (PHP) yang paling banyak digunakan:
https://github.com/symfony/Routing
https://github.com/kriswallsmith/assetic
Keduanya sama-sama sangat kuat.
sumber
Saya ingin menambahkan pengalaman saya di sini sebagai pengorbanan. Di PostgreSQL, setidaknya, dampak kinerja sangat minim dalam hal server db. Gumpalan besar disimpan dalam file terpisah, bukan di tabel tumpukan utama sehingga memindahkannya dari cara operasi yang dapat menghitung sejumlah besar catatan. Dbs lain dapat melakukan hal serupa.
Keuntungan utama adalah kemampuan untuk menyimpan semua data terkait di satu tempat untuk keperluan atomisitas dan cadangan. Ini sangat mengurangi kemungkinan terjadi kesalahan.
Kerugian utama bukanlah yang saya lihat dibahas di atas, dan itu penggunaan memori di front-end. Saya tidak tahu persis bagaimana setiap db menangani ini jadi ini mungkin tergantung pada implementasi tetapi untuk PostgreSQL, datanya masuk sebagai string ASCII yang lolos (mungkin heksadesimal, mungkin dengan eskrip inline). Ini kemudian harus dikonversi kembali ke biner di ujung depan. Banyak kerangka kerja yang saya lihat untuk melakukan ini melibatkan melewati nilai (bukan sebagai referensi) dan kemudian membangun string biner baru berdasarkan itu. Saya menghitung bahwa menggunakan Perl untuk melakukan ini akhirnya menggunakan berkali-kali memori biner asli untuk menyelesaikannya.
Putusan: Jika file hanya diakses sesekali saya akan menyimpan di db. Jika mereka sering dan berulang kali diakses, setidaknya dengan PostgreSQL, saya pikir biayanya melebihi manfaatnya.
sumber
Kembali pada hari itu, Microsoft meningkatkan kemampuan untuk menyimpan gambar (dan tipe data gumpalan serupa) dalam database. Itu adalah fitur baru yang keren dari SQL Server 2000 (saya cukup yakin itu 2000, bukan 7,0) dan banyak orang ikut-ikutan.
Menyimpan BLOBS dalam database memiliki kelebihan dan kekurangan:
Di satu sisi, semua data Anda dan gambar atau dokumen terkait dapat disimpan dan diakses di satu tempat. Pengguna aplikasi tidak memerlukan izin jaringan khusus, karena SQL yang melayani gambar / file / dokumen.
Di sisi lain, basis data Anda dapat tumbuh cukup besar, tergantung pada ukuran dan jumlah BLOBS yang Anda simpan. Ini memengaruhi cadangan, persyaratan penyimpanan, operasi pemulihan yang sensitif terhadap waktu, dll.
SQL Server 2008 memperkenalkan streaming file. Basis data berisi pointer ke file, file berada di server tidak dalam database, tetapi ketika Anda membuat cadangan database file juga didukung.
Cadangan Anda bisa menjadi cukup besar, tetapi Anda tidak berakhir dengan file / dokumen / blob / gambar yatim.
Preferensi pribadi saya adalah membiarkan database menyimpan pointer / lokasi jaringan, dan membiarkan server file menangani file. Server file lebih baik dioptimalkan untuk tugas-tugas seperti itu.
sumber
SELECT image FROM table
di SSMS dan memvalidasi bahwa gambar yang tepat ada di sana?Jangan menyimpan file dalam database.
Setiap orang, tanpa terkecuali, yang dapat menjalankan RDBMS di pasar sudah memiliki database khusus untuk menyimpan file, dan RDBMS sendiri yang menggunakannya! Database itu adalah sistem file . Sekarang mari kita bicara tentang beberapa kelemahan potensial menyimpan file dalam database, serta beberapa faktor mitigasi khusus untuk menyimpan file dalam database.
Tidak ada filehandes ke file dalam database. Apa artinya ini?
Programmer-talk: Anda TIDAK BISA mencari (
fseek
), tidak ada kemampuan untuk mengelola sumber daya dengan akses asinkron (asyncio
atauepoll
), tidak adasendfile
(menghemat salinan dari ruang kernel Anda).Aplikasi praktis: Ingin mengirim video atau gambar ke klien melalui HTTP2 / 3? Jika ada di database, maka Anda harus terlebih dahulu menanyakannya. Untuk kueri apa pun yang mengembalikan file itu, Anda harus menunggu seluruh kueri untuk menyimpulkan sebelum file itu dapat pindah ke langkah berikutnya. Dalam instalasi produksi dengan rdbms pada server yang berbeda dari server web, pertama - tama Anda harus mentransfer file sepenuhnya dari rdbms ke server web daripada streaming melalui. Namun, jika lapisan transportasi menyediakan abstraksi sistem file (yang bahkan didukung NFS), Anda dapat mencari setengah jalan melalui file dan segera mulai mengalirkannya kembali ke klien tanpa buffering lebih dari file dari yang diperlukan. Ini secara rutin dilakukan oleh server webnginx , Apache , PureFTP, dan ProFTP.
Salin dua kali lipat pada RDBMS. Dengan fakta bahwa itu ada di database, Anda mungkin akan menulisnya dua kali. Setelah dalam log tulis-depan (WAL), dan kemudian kembali ke tablespace.
Tidak ada pembaruan, pernah MVCC berarti tidak ada yang diperbarui, hanya disalin lagi dengan modifikasi, dan kemudian baris lama ditandai sebagai kedaluwarsa (dihapus). Setiap pembaruan ke file, akan membutuhkan penulisan seluruh baris , bukan hanya file seluruh baris. Filesystem dapat menyediakan ini juga, dengan penjurnalan data tetapi Anda jarang membutuhkannya.
Pembacaan file dan transfer untuk memperlambat permintaan. Jika file itu sendiri disimpan pada baris yang perlu Anda query, seluruh baris harus menunggu file untuk ditransfer, atau Anda harus mengeluarkan dua pertanyaan terpisah .
Penggunaan memori pada klien-DB. DB-client (libpq, jdbc, odbc, freetds, dll) atau sejenisnya kemungkinan akan buffer permintaan dalam memori. Ketika buffer dalam memori habis, ia dapat memulai buffer-disk atau bahkan lebih buruk lagi mungkin jatuh kembali ke kernel untuk di-paged ke disk.
Banyak basis data yang dipermasalahkan menyediakan kemampuan untuk membunuh dan menuai kueri ketika terlalu banyak menghabiskan waktu, atau sumber daya. Perlu diingat bahwa transfer file tidak akan dalam implementasi apa pun diperinci. Apakah permintaan itu terbunuh setelah 3 detik? Atau apakah perlu 1 detik dan backend menghabiskan 2 detik mentransfer file? Bukan hanya "terperinci", bagaimana Anda akan secara efektif menyatakan berapa banyak waktu yang dibutuhkan sebuah kueri ketika 99,9% kueri mengembalikan 1 KB, dan yang lainnya mengembalikan 1 GB?
XFS dan BTRFS tanpa -copy-on-write atau de-deduplikasi mendukung copy-on-write dan de-duplikasi secara transparan. Ini berarti memiliki gambar yang sama di mana-mana, atau membutuhkan salinan kedua dapat ditangani secara transparan oleh sistem file. Namun, jika file tersebut tidak berdiri sendiri, dan baik pada baris atau di toko sistem file kemungkinan tidak dapat memotongnya.
Integritas banyak orang di sini berbicara tentang integritas. Menurut Anda apa yang lebih baik dalam mendeteksi korupsi sistem file, aplikasi yang menggunakan filesystem atau utilitas inti filesystem? Simpan file dalam satu baris, atau out-of-line dan korupsi sistem file apa pun akan mengaburkan database.
xfs_repair
sangat bagus untuk memulihkan ketika Anda memiliki filesystem atau kerusakan hard drive, dan jika gagal itu masih akan jauh lebih mudah untuk melakukan forensik data.Migrasi cloud jika Anda ingin menyimpan file di SAN atau cloud Anda akan mengalami lebih banyak kesulitan karena sekarang migrasi penyimpanan adalah migrasi database. Jika file Anda misalnya disimpan di sistem file, Anda dapat dengan mudah memindahkannya ke S3 (dan dengan sesuatu seperti
s3fs
itu bisa transparan).Pengecualian
Menyimpan file dalam database memiliki beberapa kasus penggunaan yang valid,
Mitigasi
Beberapa database memiliki gagasan tentang "sumber daya yang dikelola secara eksternal" di mana database mengelola file secara pribadi pada disk seperti
PostgreSQL melalui infrastruktur Object Besar menyediakan filehandle ke sumber daya selama durasi transaksi.
Infrastruktur filestream SQL Server 2017 menyediakan akses sementara yang berlangsung selama durasi transaksi yang dapat Anda gunakan untuk mendapatkan File Path dan membuka File Handle.
Oracle menyediakan
BFILE
(ini tidak ada hubungannya dengan hal-hal LOB internal mereka yang disebutSecureFile
Beberapa database menyimpan objek biner besar out-of-line atau bisa, seperti Oracle SecureFile. Ini memungkinkan Anda untuk memperbarui baris, tanpa menulis ulang file.
Beberapa database seperti Oracle melakukan MVC mereka tanpa log WAL dan tidak perlu menggandakan file tersebut.
Beberapa database, seperti SQL Server dan Oracle memberikan kemampuan untuk "mengalirkan" data dari file tanpa harus memiliki pegangan file untuk itu. Ini mungkin atau mungkin tidak berjalan pada koneksi yang berbeda dari permintaan databaes. Tetapi kuncinya di sini adalah bahwa sementara Anda dapat melakukan streaming file (secara teori), saya tidak dapat menemukan bukti produk apa pun yang tidak dibuat oleh penyedia yang menggunakan fitur itu. Misalnya, di mana jembatan NGINX / Apache untuk memungkinkan Anda melakukan ini?
Oracle menyediakan deduplikasi, kompresi, dan enkripsi opsional melalui penyimpanan Internal-LOB (seperti SecureFile).
Kesimpulan
Skenario kasus terburuk ketika Anda meletakkan file dalam database sangat buruk untuk kinerja, dan kompatibilitas dengan tooling. Itu selalu tergantung pada implementasi. Tidak ada cara adalah database yang lebih baik di menjadi sistem file maka sistem file. Dalam segala hal, ini adalah kompromi dan bahkan ketika Anda mendapatkan fitur mitigasi yang kuat (seperti halnya SecureFile), perkakasnya sangat buruk sehingga benar-benar tidak lebih dari titik pemasaran kecuali seluruh tumpukan Anda dibangun oleh penyedia RDBMS.
Buat tetap sederhana, dan aturan umum adalah menjaga file keluar dari DB .
Larutan
Bagaimana seharusnya Anda menyimpan file, atau mengabstraksi sistem file sedemikian rupa agar berfungsi secara efektif bagi banyak penyewa dan pengguna? Saya sebagian untuk hashing isi file. Ini sangat umum hari ini dan berfungsi dengan baik.
sumber
Meskipun sebagian tergantung pada aplikasi / lingkungan (termasuk orang), saya akan pergi untuk gumpalan.
Menyimpan segala sesuatu di database berarti replikasi berfungsi untuk data file. Anda memerlukan mekanisme terpisah untuk menyinkronkan file FS.
Pada beberapa aplikasi, sistem file seharusnya tidak dimodifikasi. Misalnya, di situs web produksi, saya akan menghindari penggunaan sistem file untuk data yang tidak dapat dibuang (situs hidup di bawah SCM, data dalam database).
Dengan asumsi kami memiliki banyak pengguna / aplikasi dengan izin terpisah, maka setiap penyimpanan sistem file memberikan peluang untuk perbedaan dalam hak akses DB dan FS.
Perbaikan yang saya pertimbangkan untuk membuat penyimpanan BLOB adalah untuk memotong data jika itu masuk akal; jika Anda hanya membutuhkan 512 byte dari BLOB 20Mb, akses seperti sektor ini adalah keuntungan nyata, terutama jika Anda berurusan dengan klien jarak jauh (dan sekali lagi, pembaruan parsial menciptakan lalu lintas replikasi yang jauh lebih sedikit).
sumber
Pilihan saya tidak untuk keduanya. Simpan data dalam sistem seperti Amazon S3 atau CDN Microsft dan simpan URL itu dalam database.
Dengan cara ini Anda mendapatkan keandalan memiliki data yang selalu dapat diakses tanpa memiliki database berukuran monster yang harus dihadapi.
sumber
Untuk postgres:
Ini sebenarnya lurus ke depan. Ada
BYTEA
tipe yang dapat digunakan untuk menyimpan string biner. Per default, tidak ada utiliti build seperti yang disebutkan untuk MS atau Oracle. Jadi menyimpan banyak file besar dan mengambilnya bisa membosankan. Anda juga perlu melakukan konversi file dalam aplikasi (seperti denganByteStream
atau serupa, tidak tahu bagaimana ini bekerja dengan file MS / Oracle spesifik <-> solusi database). Ada jugalo
tipe, yang membantu pekerjaan mengelola BLOB karena beberapa manajemen internal tipe ini mungkin tidak melacak referensi.sumber
Bagikan pengalaman saya tentang MS SQL server dan sejumlah besar file. Kami menyimpan file di server file. Database memiliki dua tabel, satu untuk folder file dan kredensial akses, satu untuk nama file. Sangat mudah untuk memelihara database dan file. Anda dapat dengan mudah memindahkan file bahkan melintasi server, hanya perlu memodifikasi tabel folder.
sumber