Apa tempat terbaik untuk menyimpan gambar yang diunggah, database SQL atau sistem file disk?

147

Saya sedang menulis aplikasi yang memungkinkan pengguna untuk mengunggah gambar ke server. Saya berharap sekitar 20 gambar per hari semua jpeg dan mungkin tidak diedit / diubah ukurannya. (Ini adalah pertanyaan lain, bagaimana mengubah ukuran gambar di sisi server sebelum menyimpan. Mungkin seseorang dapat menjatuhkan sumber daya .NET untuk itu di komentar atau lebih). Sekarang saya bertanya-tanya apa tempat terbaik untuk menyimpan gambar yang diunggah.

  • Simpan gambar sebagai file dalam sistem file dan buat catatan dalam tabel dengan jalur yang tepat ke gambar itu.

  • Atau, simpan gambar itu sendiri dalam tabel menggunakan tipe data "gambar" atau "data biner" dari server database.

Saya melihat kelebihan dan kekurangan di keduanya. Saya suka a) karena saya dapat dengan mudah memindahkan file dan hanya perlu mengubah entri tabel. Di sisi lain saya tidak suka menyimpan data bisnis di server web dan saya tidak benar-benar ingin menghubungkan server web ke sumber data lain yang menyimpan data bisnis (untuk alasan keamanan) saya suka b) karena semua informasinya di satu tempat dan mudah diakses oleh kueri. Di sisi lain, basis data akan menjadi sangat besar segera. Mengalihdayakan data itu menjadi lebih sulit.

Tobias
sumber
2
Saya tidak menemukannya, di mana?
Tobias
6
Di sini stackoverflow.com/questions/3748/…
jason saldo
Kemungkinan duplikat dari Menyimpan Gambar dalam DB - Ya atau Tidak?
Liam

Jawaban:

95

Saya biasanya menyimpan file di sistem file, karena memang ada gunanya, meskipun ada pengecualian. Untuk file, sistem file adalah solusi yang paling fleksibel dan performan (biasanya).

Ada beberapa masalah dengan menyimpan file di database - file umumnya jauh lebih besar dari baris rata-rata Anda - set hasil yang berisi banyak file besar akan menghabiskan banyak memori. Juga, jika Anda menggunakan mesin penyimpanan yang menggunakan kunci-tabel untuk menulis (misalnya ISAM), tabel file Anda mungkin sering dikunci tergantung pada ukuran / laju file yang Anda simpan di sana.

Mengenai keamanan - Saya biasanya menyimpan file dalam direktori yang berada di luar root dokumen (tidak dapat diakses melalui permintaan http) dan melayani mereka melalui skrip yang memeriksa otorisasi yang tepat terlebih dahulu.

Eran Galperin
sumber
7
Bisakah Anda jelaskan kepada saya paragraf terakhir (Mengenai keamanan) dalam hal rincian teknis atau petunjuk apa pun akan sangat membantu. Terima kasih.
VishwaKumar
39
(Untuk semua Anda yang googler di luar sana) Jika Anda memiliki root situs Anda dikonfigurasi ke folder "publik" (seperti di my_website / public / bukan hanya my_website /), Anda dapat menyimpan gambar di folder my_website / my_images dengan sisa file aplikasi Anda. Maka tag img Anda akan merujuk "my_website / image.php? Img_id = 55" alih-alih "my_website / avatar.png", dan skrip image.php Anda akan, setelah memverifikasi kredensial Anda dan mengurai id yang Anda berikan, mengembalikan yang sebenarnya gambar. Dengan begitu, gambar hanya dapat dilihat oleh pengguna login yang benar.
Kapten Hypertext
8
hei kapten, Anda harus mengubahnya menjadi jawaban yang sebenarnya sehingga Anda bisa mendapatkan poin $$$
Andrew
4
tolong tambahkan beberapa catatan lagi tentang keamanan / mencegah file merusak situs web Anda
Andrew
1
Itu tidak akan skala, ada batasan pada jumlah file dalam folder dan jika Anda berencana untuk membagi file Anda di beberapa folder maka itu akan menambah kompleksitas pengindeksan file (Untuk mengidentifikasi di mana file itu sebenarnya disimpan). Apalagi pencarian akan sangat lambat.
Hardik
43

Satu-satunya manfaat untuk opsi B adalah memiliki semua data dalam satu sistem, namun itu manfaat palsu! Anda mungkin berpendapat bahwa kode Anda juga merupakan bentuk data, dan karena itu juga dapat disimpan dalam basis data - bagaimana Anda menyukainya?

Kecuali Anda memiliki case unik:

  • Logika bisnis termasuk dalam kode.
  • Data terstruktur termasuk dalam database (relasional atau non-relasional).
  • Data massal termasuk dalam penyimpanan (sistem file atau lainnya).

File, Kode, Data

Tidak perlu menggunakan sistem file untuk menyimpan file. Sebagai gantinya Anda dapat menggunakan penyimpanan cloud (seperti Amazon S3 ) atau Infrastruktur sebagai layanan di atasnya (seperti Uploadcare ):

https://uploadcare.com/upload-api-cloud-storage-and-cdn/

Tetapi menyimpan file dalam database adalah ide yang buruk.

David Avsajanishvili
sumber
23

Flickr menggunakan sistem file -mereka mendiskusikan alasannya di sini

Martin Beckett
sumber
14

Saya tahu ini adalah pos lama. Tetapi banyak pengunjung ke halaman ini tidak mendapatkan apa pun yang terkait dengan pertanyaan itu. Khusus untuk pemula.

Cara mengunggah dan menyimpan gambar atau file di situs web kami:

Untuk situs web statis mungkin tidak ada masalah karena penyimpanan file untuk beberapa hosting berbagi masih memadai. Masalahnya berasal dari situs web dinamis ketika menjadi lebih besar. Database yang lebih besar bisa ditangani, tetapi file yang lebih besar seperti gambar menjadi masalah. Ada dua jenis gambar di situs web:

  1. Gambar berasal dari administrator untuk blog dinamis. Biasanya, gambar-gambar ini telah dioptimalkan sebelum diunggah.

  2. Gambar dari pengguna jika pengguna diizinkan untuk mengunggah gambar seperti avatar. Atau pengguna dapat membuat konten blog dan menaruh beberapa gambar dari editor teks. Gambar seperti ini sulit diprediksi ukurannya. Pengguna dapat mengunggah gambar besar hanya untuk konten kecil dengan mengubah ukuran ukuran tampilan tetapi tidak mengubah ukuran ukuran gambar.

Dengan mengabaikan item no. 1 di atas, solusi cepat untuk item no. 2 dapat diselesaikan sementara oleh kiat-kiat berikut jika kami tidak memiliki fungsionalitas pengoptimal gambar di situs web kami:

  1. Jangan izinkan pengguna mengunggah langsung dari editor teks dengan mengarahkan mereka ke galeri gambar. Pada halaman ini pengguna harus mengunggah file terlebih dahulu sebelum dapat tertanam dalam konten. Metode ini disebut sebagai File Manager.

  2. Gunakan fungsi pangkas gambar untuk pengguna untuk mengunggah gambar. Ini akan membatasi ukuran gambar bahkan pengguna mengunggah file yang sangat besar. Gambar akhir adalah hasil dari gambar yang dipotong. Kita dapat menentukan ukuran di sisi server dan hanya menerima misalnya 500Kb atau lebih rendah.

Sekarang, itu hanya sementara. Untuk solusi akhir, pertanyaannya diulangi:

  • Bagaimana menangani penyimpanan gambar besar?
  • Ubah ukuran atau ubah ekstensi.
  • Bagaimana situs web atau e-commerce besar atau sedang menangani penyimpanan file untuk gambar mereka?

Apa yang bisa kita lakukan:

  1. Bermigrasi dari VPS hosting berbagi. Tidak cukup? Kemudian lebih tinggi dengan meningkatkan ke Dedicated.

  2. Buat server Anda sendiri untuk penyimpanan file. Googling melakukannya. Ini tidak sesulit yang Anda pikirkan. Beberapa orang melakukannya untuk situs web mereka.

  3. Cara mudah adalah menggunakan layanan penyimpanan file CDN.

Oke, 1 dan 2 agak mahal. Tapi no 3 menurut saya adalah solusi terbaik.

Beberapa layanan CDN memungkinkan Anda menyimpan file web sebanyak yang Anda inginkan.

Pertanyaan, "bagaimana cara mengunggah file ke CDN dari situs web kami?"

Jangan khawatir, begitu Anda mendaftar, biasanya gratis, Anda akan mendapatkan panduan cara mengunggah file dan mendapatkan tautannya dari / ke situs web Anda. Anda akan mendapatkan API dan banyak lagi. Mudah.

Beberapa penyedia memberi kami layanan gratis selama 14 hari dengan penyimpanan dan bandwidth terbatas. Tapi itu tidak apa-apa untuk titik awal. Satu-satunya masalah adalah karena 'orang tidak pernah mencoba'.

Semoga ini bisa membantu pemula.

Sulung Nugroho
sumber
13

Kami telah memiliki klien bersikeras opsi B (storage database) beberapa kali pada beberapa backends berbeda, dan kami selalu akhirnya akan kembali ke pilihan A (storage filesystem) akhirnya.

Gumpalan besar seperti itu belum ditangani dengan cukup baik bahkan oleh SQL Server 2005, yang merupakan yang terbaru yang kami coba.

Secara khusus, kami melihat kembung yang serius dan saya pikir mungkin mengunci masalah.

Satu catatan lain: jika Anda menggunakan penyimpanan berbasis NTFS (windows server, dll) Anda mungkin mempertimbangkan untuk mencari cara menempatkan ribuan dan ribuan file dalam satu direktori. Saya tidak yakin mengapa, tetapi kadang-kadang sistem file tidak mengatasi dengan baik situasi itu. Jika ada yang tahu lebih banyak tentang ini, saya akan senang mendengarnya.

Tapi saya selalu mencoba menggunakan subdirektori untuk memecah hal-hal sedikit. Tanggal pembuatan sering bekerja dengan baik untuk ini:

Gambar / 2008/12/17 / .jpg

... Ini memberikan tingkat pemisahan yang layak, dan juga sedikit membantu selama proses debug. Klien Explorer dan FTP sama-sama dapat tersedak sedikit ketika ada direktori yang sangat besar.

EDIT: Hanya catatan singkat untuk 2017, dalam versi SQL Server yang lebih baru, ada opsi baru untuk menangani banyak BLOB yang seharusnya menghindari kelemahan yang saya bahas.

EDIT: Catatan singkat untuk tahun 2020, Penyimpanan Gumpalan di AWS / Azure / dll juga telah menjadi pilihan selama bertahun-tahun sekarang. Ini sangat cocok untuk banyak proyek berbasis web karena murah dan seringkali dapat menyederhanakan masalah tertentu seputar penyebaran, penskalaan ke beberapa server, men-debug lingkungan lain jika diperlukan, dll.

Brian MacKay
sumber
4
Peringatan bagus tentang jumlah file pada direktori yang sama. Ini dapat memberikan kesalahan terlalu sulit untuk ditemukan di lingkungan produksi.
digao_mb
1
Saya pernah mengalami masalah ini sebelumnya. NTFS berperilaku tak terduga dengan sekitar 10.000 file di folder.
Faiz
1
Tidak hanya NTFS tetapi juga BTRFS, yang juga memiliki masalah menangani sejumlah besar gambar dalam satu folder. Yaitu jika Anda mencoba untuk lsitu akan memakan waktu lama (hang). Atau hapus.
sunapi386
11

Saya baru-baru ini membuat aplikasi PHP / MySQL yang menyimpan file PDF / Word dalam tabel MySQL (sebesar 40MB per file sejauh ini).

Pro:

  • File yang diunggah direplikasi ke server cadangan bersama dengan yang lainnya, tidak diperlukan strategi cadangan yang terpisah (ketenangan pikiran).
  • Menyiapkan server web sedikit lebih sederhana karena saya tidak perlu memiliki unggahan / folder dan memberi tahu semua aplikasi saya di mana itu.
  • Saya dapat menggunakan transaksi untuk pengeditan untuk meningkatkan integritas data - Saya tidak perlu khawatir tentang file yatim dan hilang

Cons:

  • mysqldump sekarang membutuhkan waktu lama karena ada 500MB data file di salah satu tabel.
  • Secara keseluruhan tidak terlalu memory / cpu efisien jika dibandingkan dengan filesystem

Saya sebut implementasi saya sukses, ini mengurus persyaratan cadangan dan menyederhanakan tata letak proyek. Performanya baik untuk 20-30 orang yang menggunakan aplikasi.

terlalu banyak php
sumber
6

Saya menggunakan gambar yang diunggah di situs web saya dan saya pasti akan mengatakan opsi a).

Satu hal lain yang saya sangat rekomendasikan adalah segera mengubah nama file dari apa yang pengguna beri nama foto, menjadi sesuatu yang lebih mudah dikelola. Misalnya sesuatu dengan tanggal dan waktu untuk mengidentifikasi secara unik setiap gambar.

Ini juga membantu untuk menghapus nama file pengguna dari setiap karakter aneh untuk menghindari komplikasi di masa depan.

barfoon
sumber
6

Ubah ukuran gambar secara pasti, dan periksa formatnya jika Anda bisa. Ada beberapa kasus file berbahaya yang diunggah dan dilayani oleh host tanpa disadari - misalnya, kerentanan GIFAR memungkinkan Anda untuk menyembunyikan applet java berbahaya dalam file GIF, yang kemudian dapat membaca cookie dalam konteks saat ini dan mengirimkannya ke situs lain untuk serangan skrip lintas situs. Mengubah ukuran gambar biasanya mencegah hal ini, karena munges kode tertanam. Sementara serangan ini telah diperbaiki oleh tambalan JVM, secara naif melayani file-file biner tanpa menggosoknya akan membuka Anda ke seluruh jajaran kerentanan.

Ingat, sebagian besar pemindai virus hanya dapat berjalan melawan sistem file - jika Anda menyimpan binari di DB, Anda tidak akan dapat menjalankan pemindai dengan mudah.

Tim Howland
sumber
4

Ada semacam pendekatan hybrid di SQL Server 2008 yang disebut datestype filestream yang dibicarakan di RunAs Radio # 74 , yang merupakan jenis yang terbaik dari kedua dunia. Kebanyakan orang tidak memiliki otion 2008, tetapi jika Anda melakukannya, opsi ini terlihat cukup keren

Charles Graham
sumber
4

Ini pada dasarnya saya lakukan.

  1. Simpan gambar yang diunggah dalam direktori atau memori sementara.
  2. Memproses gambar itu sebelum menyimpannya secara permanen. 2.1. Koreksi warna 2.2. Kompres 2.3. Buat beberapa salinan berdasarkan dimensi gambar 2.4. Ganti nama dengan sufiks .xl, .lg, .md, .sm dll
  3. Kemas semua file gambar yang diproses (dari satu file) di dalam folder dengan nama folder idyang akan disimpan dalam database untuk setiap baris / dokumen bersama dengan image file name(atau mungkin nama acak sebagai nama gambar).
  4. Buat folder yyyy / mm / d path jika tidak ada. Misalnya 2016/08/21. Ingat jalur itu dan simpan dalam database untuk dokumen dan baris yang sama.
  5. Pindahkan idfolder gambar ke pathfolder. (Folder path dapat ditemukan di folder / var / konten web.)
  6. Siram buffer memori atau hapus file sementara.

Saat Anda perlu mengakses gambar apa pun yang disebutkan dalam dokumen, Anda memiliki jalur dan id folder selain berisi gambar. Sebagai contoh/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

Dengan cara ini jika Anda harus menghapus semua file gambar yang diproses, cukup hapus folder dan isinya secara rekursif.

Uday Hiwarale
sumber
3

Sebagian besar implementasi adalah opsi A.

Dengan opsi B, Anda membuka seluruh kaleng besar whoop4ss saat Anda menyusun bit-bit dari database menjadi sesuatu yang dapat ditampilkan pada browser ... Juga, jika db turun, gambar tidak tersedia.

Saya tidak berpikir bahwa ruang terlalu banyak masalah ... Drive terabyte adalah beberapa ratus dolar sekarang.

Kami menerapkan dengan opsi A karena kami tidak punya waktu atau sumber daya untuk melakukan opsi B.

mson
sumber
3

Untuk mengubah ukuran otomatis, coba imagemagick ... ini digunakan untuk banyak sistem manajemen konten / sumber foto utama ... dan saya percaya ada beberapa ekstensi .net untuk itu.

jle
sumber
2

Kami menggunakan A. Saya akan meletakkannya di drive bersama (kecuali Anda tidak berencana menjalankan lebih dari satu server).

Jika saatnya tiba ketika ini tidak akan skala untuk Anda maka Anda dapat menyelidiki mekanisme caching.

csexton
sumber
2

Tentu saja, secara positif opsi A. Yang lain telah menyebutkan bahwa basis data umumnya tidak sesuai dengan BLOB, baik yang dirancang untuk melakukannya atau tidak. Filesystem, di sisi lain, hidup untuk hal ini. Anda memiliki opsi untuk menggunakan RAID striping, menyebarkan gambar di banyak drive, bahkan menyebarkannya di server yang berbeda secara geografis.

Keuntungan lain adalah backup / replikasi database Anda akan mengerikan.

dj_segfault
sumber
2

Untuk alasan keamanan, ini juga merupakan praktik terbaik untuk menghindari masalah yang disebabkan oleh Pengendalian Konten IE yang dapat memungkinkan penyerang mengunggah JavaScript di dalam file gambar, yang mungkin dieksekusi dalam konteks situs Anda. Jadi, Anda mungkin ingin mengubah gambar (memotong / mengubah ukurannya) entah bagaimana sebelum menyimpannya untuk mencegah serangan semacam ini. Jawaban ini memiliki beberapa ide lain.

Hari
sumber
2

Yah, saya punya proyek serupa di mana pengguna mengunggah file ke server. Menurut pandangan saya, opsi a) adalah solusi terbaik karena lebih fleksibel. Yang harus Anda lakukan adalah menyimpan gambar dalam folder yang dilindungi yang diklasifikasikan berdasarkan subdirektori. Direktori utama harus diatur oleh administrator karena konten tidak boleh menjalankan skrip (sangat penting) dan (baca, tulis) dilindungi agar tidak dapat diakses dalam permintaan http.

Saya harap ini membantu Anda.

domoindal
sumber
1

Jika mereka adalah file kecil yang tidak perlu diedit maka opsi B bukanlah opsi yang buruk. Saya lebih suka ini daripada menulis logika untuk menyimpan file dan menangani masalah struktur direktori gila. Memiliki banyak file dalam satu direktori itu buruk. emkay?

Jika file berukuran besar atau memerlukan pengeditan konstan, terutama dari program seperti office, maka opsi A adalah pilihan terbaik Anda.

Untuk sebagian besar kasus, ini masalah preferensi, tetapi jika Anda memilih opsi A, buat saja direktori tidak memiliki terlalu banyak file di dalamnya. Jika Anda memilih opsi B, maka buatlah tabel dengan data BLOB menjadi di basis data dan / atau grup file itu sendiri. Ini akan membantu pemeliharaan, terutama cadangan / pemulihan. Data reguler Anda mungkin cukup kecil, sedangkan data gambar Anda akan sangat besar dari waktu ke waktu.

Charles Graham
sumber
1

Itu tergantung pada kebutuhan Anda, khususnya volume, pengguna dan frekuensi pencarian. Tapi, untuk kantor kecil atau menengah, pilihan terbaik adalah menggunakan aplikasi seperti Apple Photos atau Adobe Lighroom. Mereka dikhususkan untuk menyimpan, katalog, indeks, dan mengatur sumber daya semacam ini. Tetapi, untuk organisasi besar, dengan persyaratan penyimpanan yang kuat dan jumlah pengguna yang tinggi, disarankan instantiate plataform Content Management dengan Digital Asset Management, seperti Nuxeo atau Alfresco; keduanya menawarkan sumber daya yang sangat baik untuk mengelola volume data yang sangat besar dengan metode yang disederhanakan untuk mengembalikannya. Dan, yang sangat penting: ada opsi (sumber terbuka) gratis untuk kedua platform.

Carlos Camargo
sumber