Yüklenen görüntüleri, SQL veritabanını veya disk dosya sistemini depolamak için en iyi yer hangisidir?


147

Kullanıcıların sunucuya resim yüklemesine izin veren bir uygulama yazıyorum. Günde yaklaşık 20 görüntü tüm jpeg bekliyoruz ve muhtemelen düzenlenmedi / yeniden boyutlandırıldı. (Bu başka bir soru, depolamadan önce sunucu tarafında görüntüleri nasıl yeniden boyutlandırılır. Belki birisi açıklama için bir .NET kaynağı bırakabilir lütfen). Yüklenen görüntüleri depolamak için en iyi yerin ne olduğunu merak ediyorum.

  • Görüntüleri dosya sisteminde bir dosya olarak saklayın ve bir tablo içinde o görüntünün tam yolunu içeren bir kayıt oluşturun.

  • Veya, veritabanı sunucusunun "görüntü" veya "ikili veri" veri türünü kullanarak görüntünün kendisini bir tabloda depolayın.

Her ikisinde de avantaj ve dezavantajlar görüyorum. Ben gibi) kolayca dosyaları yeniden konumlandırmak ve sadece tablo giriş değiştirmek zorunda çünkü. Öte yandan, iş verilerini web sunucusunda depolamaktan hoşlanmıyorum ve web sunucusunu iş verilerini tutan (güvenlik nedeniyle) b gibi diğer herhangi bir veri kaynağına bağlamak istemiyorum çünkü tüm bilgiler tek bir yerde ve bir sorgu ile kolayca erişilebilir. Öte yandan veritabanı çok yakında çok büyüyecek. Verilerin dış kaynaklardan sağlanması daha zor olabilir.


2
Nerede bulamadım?
Tobias


Yanıtlar:


95

Genellikle dosya sisteminde dosyaları depolarım, çünkü istisnalar olsa da, bunun için oradadır. Dosyalar için dosya sistemi en esnek ve en performanslı çözümdür (genellikle).

Dosyaları bir veritabanında depolamakla ilgili birkaç sorun vardır - dosyalar genellikle ortalama satırınızdan daha büyüktür - birçok büyük dosya içeren sonuç kümeleri çok fazla bellek tüketir. Ayrıca, yazma işlemleri için tablo kilitleri kullanan bir depolama motoru kullanırsanız (örneğin ISAM), dosya tablonuz orada sakladığınız dosyaların boyutuna / oranına bağlı olarak sık sık kilitlenebilir.

Güvenlikle ilgili olarak - Dosyaları genellikle belge kökünün dışındaki bir dizinde saklarım (http isteği ile erişilemez) ve önce uygun yetkilendirmeyi kontrol eden bir komut dosyası aracılığıyla onlara hizmet ederim.


7
Lütfen bana son paragrafı (güvenlikle ilgili) teknik detaylar açısından açıklar mısınız, yoksa herhangi bir işaretçi çok yardımcı olacaktır. Teşekkür ederim.
VishwaKumar

39
(Dışarıdaki tüm Google çalışanlarınız için) Sitenizin kök dizinini "herkese açık" bir klasörde yapılandırdıysanız (yalnızca web sitem / yerine my_website / public / dizininde olduğu gibi), görüntüleri diğer web sitemle / web sitem / my_images klasöründe uygulamanız. Daha sonra img etiketleriniz "my_website / avatar.png" yerine "my_website / image.php? İmg_id = 55" ifadesini kullanır ve kimlik bilgilerinizi doğruladıktan ve elinizdeki kimliği ayrıştırdıktan sonra gerçek görüntüsü. Bu şekilde, görüntü yalnızca uygun oturum açmış kullanıcı tarafından görüntülenebilir.
Kaptan Köprü Metni

8
hey kaptan bunu gerçek bir cevaba dönüştürmelisiniz böylece puan alabilirsiniz $$$
Andrew

4
lütfen güvenlik / dosyaların web sitenizi yok etmesini önleme hakkında birkaç not daha ekleyin
Andrew

1
Bu ölçeklenmez, klasördeki dosya sayısında bir sınırlama vardır ve dosyalarınızı birden çok klasöre bölmeyi planlıyorsanız, dosyaları dizine eklemenin karmaşıklığını ekler (Dosyanın gerçekte nerede depolandığını belirlemek için). Dahası, arama çok yavaş olacaktır.
Hardik

43

B seçeneği için tek fayda, tüm verileri tek bir sistemde bulundurmaktır, ancak bu yanlış bir faydadır! Kodunuzun da bir veri türü olduğunu ve bu nedenle veritabanında saklanabileceğini iddia edebilirsiniz - nasıl istersiniz?

Benzersiz bir durumunuz olmadığı sürece:

  • İş mantığı koda aittir.
  • Yapısal veriler veritabanına aittir (ilişkisel veya ilişkisel olmayan).
  • Toplu veriler depolamaya aittir (dosya sistemi veya diğer).

Dosyalar, Kod, Veri

Dosyaları saklamak için dosya sistemini kullanmak gerekli değildir. Bunun yerine bulut depolama ( Amazon S3 gibi ) veya Hizmet olarak Altyapı'yı ( Uploadcare gibi ) kullanabilirsiniz:

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

Ancak dosyaları veritabanında saklamak kötü bir fikirdir.



14

Bunun eski bir yazı olduğunu biliyorum. Ancak bu sayfayı ziyaret eden birçok kişi soru ile ilgili hiçbir şey almıyor. Özellikle bir acemi için.

Web sitemize resim veya dosya nasıl yüklenir ve depolanır:

Statik bir web sitesi için bazı sorun barındırma hala yeterli dosya depolama beri belki sorun yok. Sorun, büyüdükçe dinamik bir web sitesinden geliyor. Veritabanında daha büyük işlenebilir, ancak resimler gibi dosyada daha büyük bir sorun haline gelir. Bir web sitesinde iki tür resim vardır:

  1. Görüntüler dinamik blog yöneticisinden gelir. Genellikle, bu görüntüler karşıya yüklemeden önce optimize edilmiştir.

  2. Kullanıcıların avatar gibi resimleri yüklemesine izin verilir. Veya kullanıcılar blog içeriği oluşturabilir ve metin düzenleyiciden bazı resimler koyabilir. Bu tür görüntülerin boyutunu tahmin etmek zordur. Kullanıcılar, görüntü boyutunu yeniden boyutlandırarak ancak görüntü boyutunu yeniden boyutlandırarak yalnızca küçük içerik için büyük resimler yükleyebilir.

Ürün no. Yukarıdaki 1, ürün no. Web sitemizde görüntü iyileştirici işlevselliğimiz yoksa 2 aşağıdaki ipuçlarıyla geçici olarak çözülebilir:

  1. Kullanıcıların resim galerisine yönlendirerek metin düzenleyiciden doğrudan yüklemelerine izin vermeyin. Bu sayfada, kullanıcıların içeriğe gömülebilmeleri için önceden dosya yüklemeleri gerekir. Bu yönteme Dosya Yöneticisi denir.

  2. Kullanıcıların resim yüklemesi için bir resim kırp işlevini kullanın. Bu, kullanıcılar çok büyük bir dosya yüklese bile resim boyutunu sınırlar. Son görüntü kırpılan görüntünün sonucudur. Boyutu sunucu tarafında tanımlayabilir ve yalnızca örneğin 500Kb veya daha düşük olanları kabul edebiliriz.

Şimdi, bu sadece geçicidir. Son çözüm için soru tekrarlanır:

  • Büyük görüntü depolama alanı nasıl kullanılır?
  • Uzantıyı yeniden boyutlandırın veya değiştirin.
  • Büyük veya orta büyüklükte bir web sitesi veya e-ticaret resimleri için dosya depolamasını nasıl işler?

O zaman ne yapabiliriz:

  1. VPS barındırma paylaşımından taşıyın. Yeterli değil? Daha sonra Adanmış sürümüne geçerek daha yüksek.

  2. Dosya depolama için kendi sunucunuzu oluşturun. Bunu yapmak için googling. Bu düşündüğünüz kadar zor değil. Bazı insanlar bunu web siteleri için yapar.

  3. Kolay yol CDN dosya depolama hizmetini kullanmaktır.

Tamam, 1 ve 2 biraz pahalı. Ama hayır 3 Bence en iyi çözüm.

Bazı CDN servisleri istediğiniz kadar web dosyasını saklamanızı sağlar.

Soru, "Web sitemizden CDN'ye nasıl dosya yüklenir?"

Endişelenmeyin, bir kez kaydolduğunuzda, genellikle ücretsiz olarak, dosyayı nasıl yükleyeceğinizi ve bağlantılarını web sitenizden / web sitenize nasıl alacağınızı öğreneceksiniz. Bir API ve daha fazlasını alacaksınız. Bu kolay.

Bazı sağlayıcılar bize sınırlı depolama ve bant genişliği ile 14 gün boyunca ücretsiz hizmet veriyor. Ancak bu başlangıç ​​noktası için uygun olacaktır. Tek sorun 'insanlar asla denemez'.

Umarım acemi için yardımcı olacaktır.


13

Müşteriler birkaç farklı arka uçta B seçeneğinde (veritabanı depolama) birkaç kez ısrar ettiler ve sonunda her zaman A seçeneğine (dosya sistemi depolama) geri döndük.

Bunun gibi büyük BLOB'lar, en son denediğimiz SQL Server 2005 tarafından bile yeterince iyi işlenmedi.

Özellikle, ciddi şişkinlik gördük ve bence kilitleme problemleri.

Başka bir not: NTFS tabanlı depolama (windows sunucusu vb.) Kullanıyorsanız, binlerce dizini binlerce dosyaya tek bir dizine koymanın bir yolunu bulmayı düşünebilirsiniz. Neden olduğundan emin değilim, ancak bazen dosya sistemi bu durumla iyi başa çıkmıyor. Eğer kimse bu konuda daha fazla bilgi sahibi olursa, bunu duymak isterim.

Ama her zaman işleri biraz parçalamak için alt dizinleri kullanmaya çalışıyorum. Oluşturma tarihi genellikle bunun için iyi çalışır:

Görüntüler / 2008/12/17 / .jpg

... Bu iyi bir ayırma düzeyi sağlar ve hata ayıklama sırasında biraz yardımcı olur. Explorer ve FTP istemcileri gerçekten çok büyük dizinler olduğunda biraz boğabilirler.

EDIT: 2017 için sadece kısa bir not, SQL Server'ın daha yeni sürümlerinde, tartıştığım dezavantajlardan kaçınması gereken çok sayıda BLOB'u işlemek için yeni seçenekler var.

EDIT: 2020 için hızlı not, AWS / Azure / etc'deki Blob Storage, yıllardır bir seçenek olmuştur. Bu, birçok web tabanlı projeye ucuzdur ve dağıtım ile ilgili belirli sorunları basitleştirebilir, birden fazla sunucuya ölçeklendirebilir, gerektiğinde diğer ortamlarda hata ayıklayabilir, vb.


4
Aynı dizindeki dosya sayısı hakkında iyi uyarı. Bir üretim ortamında hata bulmak çok zor olabilir.
digao_mb

1
Bu sorunu daha önce vurmuştum. NTFS, bir klasördeki yaklaşık 10.000 dosyayla beklenmedik şekilde davrandı.
Faiz

1
Sadece NTFS değil, aynı zamanda bir klasörde çok miktarda görüntü ile ilgili bir problemi olan BTRFS. Yani denediyseniz lssonsuza kadar sürecek (asılı). Veya silin.
sunapi386

11

Son zamanlarda PDF'leri / Word dosyalarını MySQL tablosunda saklayan bir PHP / MySQL uygulaması oluşturdum (şu ana kadar dosya başına 40 MB kadar büyük).

Artıları:

  • Yüklenen dosyalar, diğer her şeyle birlikte yedekleme sunucusuna çoğaltılır, ayrı bir yedekleme stratejisine gerek yoktur (gönül rahatlığı).
  • Bir yükleme / klasörüm olması ve tüm uygulamalarıma nerede olduğunu söylemem gerekmediğinden web sunucusunu kurmak biraz daha basittir.
  • Veri bütünlüğünü iyileştirmek için düzenlemeler için işlemler kullanıyorum - artık ve eksik dosyalar için endişelenmem gerekmiyor

Eksileri:

  • mysqldump artık tablolardan birinde 500MB dosya verisi bulunduğundan looooong zamanını alıyor.
  • Genel olarak dosya sistemine kıyasla çok fazla bellek / işlemci verimli değil

Uygulamama başarılı diyebilirim, yedekleme gereksinimlerini karşılar ve projenin düzenini basitleştirir. Performans, uygulamayı kullanan 20-30 kişi için iyi.


6

Web sitemde yüklenen görüntüleri kullanıyorum ve kesinlikle seçenek a) diyebilirim.

Şiddetle tavsiye ediyorum başka bir şey, dosya adını kullanıcının fotoğrafı adlandırdığı şeyden, daha yönetilebilir bir şeye hemen değiştirmektir. Örneğin, her resmi benzersiz bir şekilde tanımlamak için tarih ve saat içeren bir şey.

Ayrıca, gelecekteki komplikasyonları önlemek için kullanıcının garip karakterlerin dosya adının çıkarılmasına yardımcı olur.


6

Görüntüyü kesinlikle yeniden boyutlandırın ve formatını kontrol edin. Ana bilgisayarlar tarafından istenmeden yüklenen ve sunulan kötü amaçlı dosyalar meydana geldi - örneğin, GIFAR güvenlik açığı, bir GIF dosyasında kötü amaçlı bir java uygulamasını gizlemenize izin verdi ve bu da geçerli bağlamda çerezleri okuyabilecek ve siteler arası komut dosyası saldırısı için başka bir site. Görüntüleri yeniden boyutlandırmak, gömülü kodu mühimmat ettiği için genellikle bunu önler. Bu saldırı JVM yamaları tarafından düzeltilmiş olsa da, ikili dosyaları temizlemeden saf bir şekilde sunmak sizi bir dizi güvenlik açığına kadar açar.

Unutmayın, çoğu virüs tarayıcısı sadece dosya sistemine karşı çalışabilir - ikili dosyalarınızı DB'de saklarsanız, onlara karşı çok kolay bir tarayıcı çalıştıramazsınız.



4

Bu temelde öyle.

  1. Yüklenen bir görüntüyü geçici dizinde veya bellekte saklayın.
  2. Kalıcı olarak saklamadan önce bu görüntüyü işleyin. 2.1. Renk düzeltmeleri 2.2. Sıkıştır 2.3. Görüntü boyutlarına göre birkaç kopya oluşturun 2.4. .Xl, .lg, .md, .sm vb sonekleriyle yeniden adlandırın
  3. İşlenen tüm görüntü dosyalarını (tek bir dosyadan) idherhangi bir satır / belge için veritabanında depolanacak image file name(veya görüntü adı olarak rastgele bir ad olabilir ) klasör adına sahip bir klasör içine paketleyin .
  4. Yoksa, yyyy / mm / d path klasörü oluşturun . Örneğin 2016/08/21. Aynı belge ve satır için bu yolu ve veritabanında saklayın.
  5. Görüntü idklasörünü klasöre taşıyın path. (Yol klasörü / var / web-content klasöründe bulunabilir.)
  6. Bellek arabelleğini yıkayın veya geçici dosyayı silin.

Belgede belirtilen herhangi bir görüntüye erişmeniz gerektiğinde, klasörün yolunu ve kimliğini görüntülerden çok alırsınız. Örneğin/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

Bu şekilde, işlenen tüm görüntü dosyalarını silmeniz gerekiyorsa, klasörü ve içeriği özyinelemeli olarak silmeniz yeterlidir.


3

Çoğu uygulama A seçeneğidir.

B seçeneğiyle, veritabanından bu bitleri bir tarayıcıda görüntülenebilecek bir şeye birleştirdiğinizde whoop4ss'in büyük bir kutusunu açarsınız ... Ayrıca, db kapalıysa, görüntüler kullanılamaz.

Alanın çok fazla bir sorun olduğunu düşünmüyorum ... Terabyte sürücüler şimdi birkaç yüz dolar.

A seçeneğiyle uyguluyoruz, çünkü B seçeneğini yapacak zamanımız veya kaynağımız yok.


3

Otomatik yeniden boyutlandırma için imagemagick'i deneyin ... birçok büyük açık kaynak içerik / fotoğraf yönetim sistemi için kullanılır ... ve bunun için bazı .net uzantıları olduğuna inanıyorum.


2

A'yı kullanıyoruz. Paylaşılan bir sürücüye koyacağım (birden fazla sunucu çalıştırmayı planlamıyorsanız).

Bunun sizin için ölçeklenmediği zaman gelirse, önbellekleme mekanizmalarını araştırabilirsiniz.


2

Kesinlikle, olumlu bir şekilde A seçeneği. Dosya sistemleri ise bu şeyler için yaşıyor. RAID şeritleme kullanma, görüntüleri birden fazla sürücüye yayma, hatta coğrafi olarak farklı sunucular arasında yayma seçeneğiniz vardır.

Başka bir avantajı veritabanı yedekleme / çoğaltma korkunç olurdu.



2

Güvenlik nedeniyle, saldırganların siteniz bağlamında yürütülebilecek görüntü dosyalarının içine JavaScript yüklemelerine izin verebilecek IE'nin İçerik Koklamalarının neden olduğu sorunları önlemek de en iyi uygulamadır . Bu nedenle, bu tür saldırıları önlemek için görüntüleri saklamadan önce bir şekilde dönüştürmek (kırpmak / yeniden boyutlandırmak) isteyebilirsiniz. Bu cevabın başka fikirleri var.


2

Kullanıcıların sunucuya dosya yüklediği benzer bir projem var. Benim görüşüme göre, a) seçeneği daha esnek olması nedeniyle en iyi çözümdür. Yapmanız gereken, görüntüleri alt dizinlere göre sınıflandırılmış korumalı bir klasörde saklamaktır. Ana dizin yönetici tarafından ayarlanmalıdır, çünkü içerik http komutunda erişilebilir olmamak için komut dosyaları (çok önemli) ve (okuma, yazma) korumalı olmamalıdır.

Umarım bu sana yardımcı olur.


1

Düzenlenmesi gerekmeyen küçük dosyalarsa, seçenek B kötü bir seçenek değildir. Bunu dosyaları saklamak ve çılgın dizin yapısı sorunları ile başa çıkmak için mantık yazmayı tercih ederim. Bir dizinde çok fazla dosya olması kötüdür. EMKAY?

Dosyalar büyükse veya özellikle ofis gibi programlardan sürekli düzenleme gerekiyorsa, A seçeneği en iyi seçenektir.

Çoğu durumda, bu bir tercih meselesidir, ancak A seçeneğine giderseniz, dizinlerin içinde çok fazla dosya olmadığından emin olun. B seçeneğini seçerseniz, BLOBed verilerinin bulunduğu tablonun kendi veritabanı ve / veya dosya grubunda olmasını sağlayın. Bu bakım, özellikle yedeklemeler / geri yüklemeler için yardımcı olacaktır. Görüntü verileriniz zamanla çok büyük olurken, normal verileriniz muhtemelen oldukça küçüktür .


1

Bu, gereksinimlerinize, özellikle hacime, kullanıcılara ve arama sıklığına bağlıdır. Ancak, küçük veya orta ölçekli ofisler için en iyi seçenek Apple Photos veya Adobe Lighroom gibi bir uygulama kullanmaktır. Bu tür kaynakları depolamak, kataloglamak, endekslemek ve düzenlemek için uzmanlaşmıştır. Ancak, güçlü depolama gereksinimleri ve çok sayıda kullanıcısı olan büyük kuruluşlar için, Nuxeo veya Alfresco gibi Dijital Varlık Yönetimi ile bir İçerik Yönetimi plataformunun başlatılması önerilir; her ikisi de, çok büyük miktarda veriyi, bunları geri almak için basitleştirilmiş yöntemlerle yöneten çok iyi kaynaklar sunar. Ve çok önemli: her iki platform için de ücretsiz (açık kaynak) bir seçenek var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.