none
Resim yüklemek ve indirmek RRS feed

  • Genel Tartışma

  • Herkese hayırlı cumalar;

    Bir mvc web proje geliştiriyorum, bir sipariş formu var sipariş bilgileri giriliyor kullanıcı tarafından ve sözleşmenin de fotoğrafı eklenmesi lazım codefirstte public byte[] sozlesme şeklinde veritabanımda oluşturdum, resmi nasıl ekleyeceğim ve tablomda resmi nasıl görüntüleyip o resmin indirme işlemini yapacağım, bilgilendirirmisiniz lütfen, ayrıca mobil cihazdan da resim yüklenebilir bunun içinde ayrı bir kod yazmak gerekiyor mu, yardımlarınız  için şimdiden teşekkürler.

    10 Şubat 2017 Cuma 09:59

Tüm Yanıtlar

  • Öncelikle veritabanında byte[] (dizi) nesnesi saklanamaz belki yanılıyorumdur.

    sözleşme resimlerini

    1-) bir klasörde saklayabilirsin

    2-)  ilgili resmi base64 String nesnesine dönüştürerek saklayabilirsin.

    1. yol için: Resimi yükleme sırasında bir Guid id ile resmi isimlendirirsin ve veritabanına ilgili resmin adını yazarsın ve resmi ilgili klasöre kayıt edersin.

    2. yol için ilgili resmi yükleme sırasında base64 string nesnesine çevirirsin ve veritabanına yazarsın 

    bu resimi img nesnesinin src değerine ilgili base64 değerini girerek gösterilmesini sağlayabilirsin.

    Resim yükleme ve bir resim için indirme bağlantısı oluşturma konusu ile ilgili birçok örnek kod internette bulabilirsin.

    ve mobil konusuna gelince ayrı bir kod yazman gerekmez ama burada dikkat etmen gereken konu ilgili resim yükleme sayfasının mobilde düzgün görülmesi.

    10 Şubat 2017 Cuma 13:12
  • Öncelikle veritabanında byte[] (dizi) nesnesi saklanamaz belki yanılıyorumdur.


    MS SQL'de Varbinary tipindeki alanlarda byte dizileri saklanabilir.

    pgnchess.com

    dergikapaklari.com

    10 Şubat 2017 Cuma 13:24
  • iyimiş. ama yinede resimi veritabanında saklamasını önermiyorum.
    10 Şubat 2017 Cuma 13:58
  • iyimiş. ama yinede resimi veritabanında saklamasını önermiyorum.
    Neden ?

    eneskarakara[at]gmail[nokta]com

    10 Şubat 2017 Cuma 14:03
  • Tabikide performans.

    Çok basit bir örnek vermek gerekirse:

    Eğer bir resimi veritabanında saklarsanız ilgili nesne için her istek yapıldığında veritabanından resim datasınıda okuyacaksınız.

    Fakat kullanıcının her istek gönderdiğinde sizin resmi tekrar tekrar okumanıza gerek yok çünkü zaten tarayıcı 1. istekten sonra ilgili resimi belleğe almış olacak ama siz hala resim datasını db den çekeceksiniz.

    Buradaki isteği 1 değilde 1 milyon yapın resim boyutu 1mb olsa 1mb*1 000 000 yapın bukadar mb veriyi db den okumaya çalışmak çılgınca :)

    10 Şubat 2017 Cuma 14:24
  • Neden önermiyorsunuz?

    pgnchess.com

    dergikapaklari.com

    10 Şubat 2017 Cuma 14:26
  • Tabikide performans.

    Çok basit bir örnek vermek gerekirse:

    Eğer bir resimi veritabanında saklarsanız ilgili nesne için her istek yapıldığında veritabanından resim datasınıda okuyacaksınız.

    Fakat kullanıcının her istek gönderdiğinde sizin resmi tekrar tekrar okumanıza gerek yok çünkü zaten tarayıcı 1. istekten sonra ilgili resimi belleğe almış olacak ama siz hala resim datasını db den çekeceksiniz.

    Buradaki isteği 1 değilde 1 milyon yapın resim boyutu 1mb olsa 1mb*1 000 000 yapın bukadar mb veriyi db den okumaya çalışmak çılgınca :)

    Doğrudan dosyadan okuyunca aynı istek gitmiyor mu? Aynı byte[] gelmiyor mu? O resim dosyasını byte ları veritabanından okununca da bellekte saklanmıyor mu? Ekstra olarak dosya izinlerini kontrol etmek çılgınca değil mi?
    10 Şubat 2017 Cuma 14:33
  • Veritabanında saklamak şuan her yönden avantajlı görünüyor. Tabi bildiğim kadarıyla.

    eneskarakara[at]gmail[nokta]com

    10 Şubat 2017 Cuma 19:05
  • Meseleyi tam anlamadın galiba.

    Doğrudan dosya okuduğunda 1 kullanıcı için sadece 1 istek gider.

    1 Kullanıcı A sayfasına 1000 kere istek gönderdiğinde ilgili resim 1. de sunucudan yüklenir geri kalan 999 istekde kullanıcının kendi pc önbelleğinden yüklenir.

    senin senaryonda ise 999 istekde resimler yine kullanıcının önbelleğinden yüklenecek fakat sen gerek olmadığı halde yinede resim datasını okumuş getirmiş ve ilgili datayı tekrar image olarak convert işlemini yapmış olacaksın buda senin için gereksiz performans kaybı demek olacak.

    10 Şubat 2017 Cuma 19:41
  • cidden bilemiyorum dediğin mantıklı geliyor. ama kaçırdığın bazı ayrıntılar var galiba? başka db'ye kaydedenleride gördüm emin ol senin yaptığın hesabı yapamayacak insanlar değiller ama db ye kaydediyolar. kaçırdığın ayrıntılar vardır belkide ?

    eneskarakara[at]gmail[nokta]com

    10 Şubat 2017 Cuma 20:47
  • cidden bilemiyorum dediğin mantıklı geliyor. ama kaçırdığın bazı ayrıntılar var galiba? başka db'ye kaydedenleride gördüm emin ol senin yaptığın hesabı yapamayacak insanlar değiller ama db ye kaydediyolar. kaçırdığın ayrıntılar vardır belkide ?

    eneskarakara[at]gmail[nokta]com

    Neresi mantıklı? Önce bir bu tür resim cacheleme nerde yapılıyor? Kullanıcı direk sql'den mi istekte bulunuyor? Disk dosyaları nasıl tutuyor? gibi ilk anda aklıma gelen sorular var.

    Ben olanı diyeyim. 2000 li yıllarda yaygın bir laftı. "resim db de tutulmaz!" hatta bir yıl oncesine kadar benim de  demişliğim vardır "DB şişer!" diye.


    pgnchess.com

    dergikapaklari.com

    10 Şubat 2017 Cuma 20:58
  • Performans için çözüm 1 tane değildir tabikide burada öğrenmek için soru soran bir kişiye cevap veriyorum.

    Yoksa bir çok çözüm konuşula bilir.

    Resimler için bir servis sistemi düşünülebilir.

    Rest Service + Cacheing + DB şeklinde ayrı bir sistem kurgulanabilir 

    Resimlerini versiyonlama ile client de belleklenmesini sağlayabilirsin ve gelen request de ilgili versiyonlu resmin client de bellekte bulunup bulunmadığını kontrol edip ona göre tekrar resmi okuyabilirsin ama burada bile resimler db den okunmaz direk sunucu taraflı cacheing sisteminden okursun. vs..

    10 Şubat 2017 Cuma 21:05
  • Kullanıcı durduk yere sayfaya 1000 tane istek gönderiyorsa büyük ihtimalle DDOS olarak algılanıp sunucuya gelen istekler drop edilir (Host un güvenlik yapılandırmasına göre değişir). Önbellekte tutulan veriler pek bir işe yaramaz o zaman. Ama olay sadece resimden ibaret değil bunun word belgesi var excel belgesi var pdf belgesi var. Birisi çıkar başka bir veritabanının yedeğini alır *.bak dosyasını başka bir sunucudaki veritabanına aktarır. Sıradışı bir örnek ama yelpaze geniş yani her şey olabilir. Dosyalar çok büyük değilse veritabanında tutmak her zaman daha avantajlıdır. Mesela; 

    • Resim veya değil dosyaları veritabanında tutmadığın zaman veritabanının yedeğini aldığın zaman aynı zamanda dosya sisteminin de yedeğini almak zorunda kalır. Aynı şekilde yedekten geri yükleme yağtığın zaman dosya sistemini de yedekten geri yüklemek zorunda kalırsın.
    • Bir kayıt silineceği zaman hem veritabanından hem de dosya sisteminden ayrı ayrı silmek zorunda kalırsın. Hatta Web uygulamasına dosya sisteminde silme yetkisi vermek zorunda kalırsın. Yönetilmesi çok zor bir durum ama çok tehlikeli durumlarla karşı karşıya kalabilirsin. 
    • Kayıt sileceğin bir hata oluştuğunu düşün. Transaction kullanmışsan silme işlemi geri alınır. Peki dosya sisteminden silinen dosyalar ne olacak. Transaction Rollback silinen dosyaları geri yüklemez. Veritabanında dosya olarak karşılığı olmayan kayıtlar olarak kalacaktır. 
    • Büyük dosyalar için SQL Server da FILESTREAM özelliği var. Fakat onda Encryption desteği yok. varbinarymax 2^8000 byte veri saklayabiliyor
    10 Şubat 2017 Cuma 21:34
  • Deleted
    10 Şubat 2017 Cuma 23:01
  • Kullanıcı durduk yere sayfaya 1000 tane istek gönderiyorsa büyük ihtimalle DDOS olarak algılanıp sunucuya gelen istekler drop edilir (Host un güvenlik yapılandırmasına göre değişir). Önbellekte tutulan veriler pek bir işe yaramaz o zaman. Ama olay sadece resimden ibaret değil bunun word belgesi var excel belgesi var pdf belgesi var. Birisi çıkar başka bir veritabanının yedeğini alır *.bak dosyasını başka bir sunucudaki veritabanına aktarır. Sıradışı bir örnek ama yelpaze geniş yani her şey olabilir. Dosyalar çok büyük değilse veritabanında tutmak her zaman daha avantajlıdır. Mesela; 

    • Resim veya değil dosyaları veritabanında tutmadığın zaman veritabanının yedeğini aldığın zaman aynı zamanda dosya sisteminin de yedeğini almak zorunda kalır. Aynı şekilde yedekten geri yükleme yağtığın zaman dosya sistemini de yedekten geri yüklemek zorunda kalırsın.
    • Bir kayıt silineceği zaman hem veritabanından hem de dosya sisteminden ayrı ayrı silmek zorunda kalırsın. Hatta Web uygulamasına dosya sisteminde silme yetkisi vermek zorunda kalırsın. Yönetilmesi çok zor bir durum ama çok tehlikeli durumlarla karşı karşıya kalabilirsin. 
    • Kayıt sileceğin bir hata oluştuğunu düşün. Transaction kullanmışsan silme işlemi geri alınır. Peki dosya sisteminden silinen dosyalar ne olacak. Transaction Rollback silinen dosyaları geri yüklemez. Veritabanında dosya olarak karşılığı olmayan kayıtlar olarak kalacaktır. 
    • Büyük dosyalar için SQL Server da FILESTREAM özelliği var. Fakat onda Encryption desteği yok. varbinarymax 2^8000 byte veri saklayabiliyor
    Ek olarak resimler, dosyalar dizin içerisinde açık erişilebilir tutulur. 

    pgnchess.com

    dergikapaklari.com

    11 Şubat 2017 Cumartesi 01:32
  • Mesela ben db de saklıyorum resimleri. Önbellekte tutulup resim varsa önbellekten yükle db den çekme boşuna gibi işlemleri extradan yapmam mı gerekiyor? eğer öyleyse nasıl yapabilirim bir örnek yada makale önersenizde olur


    eneskarakara[at]gmail[nokta]com

    11 Şubat 2017 Cumartesi 10:20

  • senin senaryonda ise 999 istekde resimler yine kullanıcının önbelleğinden yüklenecek fakat sen gerek olmadığı halde yinede resim datasını okumuş getirmiş ve ilgili datayı tekrar image olarak convert işlemini yapmış olacaksın buda senin için gereksiz performans kaybı demek olacak.

    Buna kötü kod/mimari diyoruz. Dosyayı veritabanından veya bellekten! okuyup istemciye gönderirken Last-Modified bilgisini headerda gönderirsin. İstemci de bu dosyayı daha önce çekmiş ise If-Modified-Since headerı ile sana kendisindeki değişim tarihini döner. Sen sunucuda gerekli karşılaştırmayı yapar ve dosya geçerli bir dosya ise duruma göre Http 304 veya 200 dönersin. Yani ilk durum söylediğin senaryo aynen geçerli olmuş olur. 1 request atar dosyayı db den okur kalan 999 için sadece değişmedi bilgisi gider. 

    Aynı zamanda yine headerlar (Expires, max-age,etag...) vasıtasıyla istemcinin belirli bir süre boyunca dosya için istek bile atmasının gereksiz olduğunu söyleyebilirsin. Bu işleri yapmak bile I/O ile uğraşmaktan hızlı olabilir yeri geldiğinde. Yani kalan 999 istek için istemci sunucuya uğramaz.

    Output Cache kullanımı ile de bu dosya ilk kişinin isteğinde belleğe alınır. Ayarlacağınız süre boyunca da diğer kullanıcılar için bellekten doğrudan yanıt dönülür.

    Bu kullanım mantığı ile dosyanın varyantlarını üretmek mümkün de olur. Örneğin, kullanıcı resmin 50px yüksekliğinde küçük görünümünü isteyebilir. Sen db den okur küçültür ve cache headerlarını belirtirsin. (Gerekirse sunucu taraflı output cacheleri de yaparsın). Böylece küçük resmin cache bilgisi orijinal resim ile aynı olmuş olur.


    DB de saklamak ölçeklendirmeyi kolaylaştırır. Aksi durumda ayrıca bir fileserver ihtiyacı doğar. 

    Veritabanları disk üzerinde geniş bir alanı tutarlar. Düzenli bir defrag durumunda dosyanın içeriği sıralı olacaktır. Dosya erişimin de muhtemelen daha hızlı olacaktır.


    DB de saklamanın yine ACID kuralları çerçevesinde ele alınacağının unutulmaması gerekir. Dikkat edilmeyen kullanımlar tablonun kilitlenmesine yol açabilir. Ve hatta bu tablonunda içinde olduğu transactionlar yüzünden yanlışlıkla tüm veritabanını kilitleyebilirsiniz. Mümkün olduğunca bu tip tabloların farklı dosyalarda tutulması, gerekiyorsa filestream yapılması ve isolation seviyelerinin düşük tutulmasını öneririm. Yönetmeyi "bana göre" kolaylaştırmak açısından da komple ayrı bir veritabanı olarak tutulması CDN kafasında hizmet vermesi de iyi olabilir. Gün gelir belki bu işi başka sunucuya taşırsınız.



    Merak edenler için :
    https://www.keycdn.com/blog/http-cache-headers/





    11 Şubat 2017 Cumartesi 14:01
    Moderatör