Aktualizacja do 2012 r., Kiedy widzimy, że rozmiary i liczba obrazów rosną i rosną we wszystkich aplikacjach ...
Potrzebujemy pewnego rozróżnienia między „oryginalnym obrazem” a „przetworzonym obrazem”, na przykład miniaturą.
Jak mówi odpowiedź Jcoby'ego, są dwie opcje, więc polecam:
użyj blob (Binary Large OBject): do oryginalnego magazynu obrazów, przy stole. Zobacz odpowiedź Ivana (nie ma problemu z tworzeniem kopii zapasowych blobów!), Dodatkowe dostarczone moduły PostgreSQL , instrukcje itp.
użyj oddzielnej bazy danych z DBlink : dla oryginalnego magazynu obrazów, w innej (zunifikowanej / wyspecjalizowanej) bazie danych. W tym przypadku wolę bajtę , ale blob jest prawie taki sam. Oddzielenie bazy danych to najlepszy sposób na „ujednoliconą usługę sieciową obrazu”.
użyj bajtu (BYTE Array): do buforowania obrazów miniatur. Buforuj małe obrazy, aby szybko wysłać je do przeglądarki internetowej (aby uniknąć problemów z renderowaniem) i zmniejszyć przetwarzanie serwera. Buforuj również istotne metadane, takie jak szerokość i wysokość. Buforowanie bazy danych jest najłatwiejszym sposobem, ale sprawdź swoje potrzeby i konfiguracje serwera (np. Moduły Apache): przechowuj miniatury w systemie plików może być lepsze, porównaj wydajność. Pamiętaj, że jest to (ujednolicona) usługa internetowa, a następnie może być przechowywana w oddzielnej bazie danych (bez kopii zapasowych), obsługującej wiele tabel. Zobacz także podręcznik typów danych binarnych PostgreSQL , testy z kolumną bajtową itp.
UWAGA 1: obecnie używanie „podwójnych rozwiązań” (baza danych + system plików) jest przestarzałe (!). Stosowanie „tylko bazy danych” zamiast podwójnej ma wiele zalet. PostgreSQL ma porównywalną wydajność i dobre narzędzia do eksportu / importu / wejścia / wyjścia.
UWAGA2: pamiętaj, że PostgreSQL ma tylko bajty , nie ma domyślnego BLOBa Oracle : "Standard SQL definiuje (...) BLOB. Format wejściowy różni się od bajtu, ale dostarczone funkcje i operatory są w większości takie same", Manual .
EDYCJA 2014 : Nie zmieniłem dzisiaj oryginalnego tekstu powyżej (moja odpowiedź brzmiała 22 kwietnia 2012, teraz z 14 głosami), otwieram odpowiedź na twoje zmiany (zobacz "Tryb Wiki", możesz edytować!), Do korekty i do aktualizacji .
Pytanie jest stabilne (odpowiedź @ Ivans '08 z 19 głosami), pomóżcie ulepszyć ten tekst.
Odpowiedź Re jcoby'ego:
Bajt będący „zwykłą” kolumną oznacza również, że wartość jest w całości odczytywana do pamięci podczas jej pobierania. Natomiast obiekty blob można przesyłać strumieniowo do standardowego wyjścia. Pomaga to zmniejszyć zużycie pamięci serwera. Szczególnie, gdy przechowujesz obrazy o rozdzielczości 4-6 MPix.
Nie ma problemu z tworzeniem kopii zapasowych obiektów blob. pg_dump udostępnia opcję "-b", która umożliwia dołączenie dużych obiektów do kopii zapasowej.
Więc wolę używać pg_lo_ *, możesz się domyślić.
Odpowiedź Re Kris Erickson:
Powiedziałbym odwrotnie :). Jeśli obrazy nie są jedynymi danymi, które przechowujesz, nie przechowuj ich w systemie plików, chyba że jest to absolutnie konieczne. Taką korzyścią jest mieć zawsze pewność co do spójności danych i mieć dane „w jednym kawałku” (DB). BTW, PostgreSQL świetnie zachowuje spójność.
Jednak, prawda, rzeczywistość często wymaga zbyt dużej wydajności ;-) i popycha cię do obsługi plików binarnych z systemu plików. Ale nawet wtedy staram się używać bazy danych jako "głównej" pamięci dla plików binarnych, ze wszystkimi innymi relacjami konsekwentnie połączonymi, zapewniając jednocześnie mechanizm buforowania oparty na systemie plików w celu optymalizacji wydajności.
źródło
BYTEA
byciu „normalną” kolumną. Postgres od wielu lat obsługuje przesyłanie strumieniowe do / zBYTEA
kolumn, co oznacza, że nie musisz przechowywać zawartości w pamięci przed zapisaniem jej w bazie danych.W bazie danych są dwie opcje:
W przeszłości używałem kolumn bajtowych z dużym powodzeniem, przechowując ponad 10 GB obrazów z tysiącami wierszy. Funkcjonalność TOAST w PG praktycznie neguje wszelkie zalety, jakie mają plamy. W obu przypadkach musisz uwzględnić kolumny metadanych dotyczące nazwy pliku, typu zawartości, wymiarów itp.
źródło
Szybka aktualizacja do połowy 2015 r .:
Możesz użyć interfejsu danych obcych Postgres , aby przechowywać pliki w bardziej odpowiedniej bazie danych. Na przykład umieść pliki w GridFS, który jest częścią MongoDB. Następnie użyj https://github.com/EnterpriseDB/mongo_fdw, aby uzyskać do niego dostęp w Postgres.
Ma to zalety, że możesz uzyskać dostęp / odczytać / zapisać / wykonać kopię zapasową w Postrgres i MongoDB, w zależności od tego, co zapewnia większą elastyczność.
Istnieją również obce opakowania danych dla systemów plików: https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers
Jako przykład możesz użyć tego: https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (zobacz tutaj krótki przykład użycia)
Daje to przewagę w postaci spójności (wszystkie połączone pliki na pewno tam są) i wszystkich innych ACID, podczas gdy nadal istnieją w rzeczywistym systemie plików, co oznacza, że możesz używać dowolnego systemu plików, a serwer sieciowy może je obsługiwać bezpośrednio ( Buforowanie systemu operacyjnego ma również zastosowanie).
źródło
Aktualizacja sprzed 10 lat W 2008 r. Dyski twarde, na których będzie można uruchomić bazę danych, będą miały znacznie inne właściwości i znacznie wyższe koszty niż dyski, na których będą przechowywane pliki. W dzisiejszych czasach istnieją znacznie lepsze rozwiązania do przechowywania plików, które nie istniały 10 lat temu, więc odwołałbym tę radę i radziłbym czytelnikom zapoznać się z innymi odpowiedziami w tym wątku.
Oryginalny
Nie przechowuj obrazów w bazie danych, chyba że jest to absolutnie konieczne. Rozumiem, że nie jest to aplikacja internetowa, ale jeśli nie ma udostępnionej lokalizacji pliku, możesz wskazać, aby zapisać lokalizację pliku w bazie danych.
wtedy możesz szybko skonfigurować serwer sieciowy i przechowywać adresy URL w bazie danych (a także ścieżkę lokalną). Podczas gdy bazy danych mogą obsłużyć LOB i 3000 obrazów (4-6 megapikseli, zakładając 500 KB na obraz) 1,5 gigabajta to niewiele, systemy plików są znacznie lepiej zaprojektowane do przechowywania dużych plików niż baza danych.
źródło
Spróbuj tego . Użyłem formatu Large Object Binary (LOB) do przechowywania wygenerowanych dokumentów PDF, z których niektóre miały rozmiar ponad 10 MB, w bazie danych i działało cudownie.
źródło
Jeśli Twoje obrazy są małe, rozważ zapisanie ich jako base64 w zwykłym polu tekstowym.
Powodem jest to, że podczas gdy base64 ma narzut na poziomie 33%, przy kompresji, która w większości znika. (Zobacz Jakie jest obciążenie miejsca związane z kodowaniem Base64? ) Twoja baza danych będzie większa, ale pakiety wysyłane przez serwer WWW do klienta nie będą. W html możesz umieścić base64 w tagu <img src = "">, co może uprościć twoją aplikację, ponieważ nie będziesz musiał wyświetlać obrazów jako plików binarnych w osobnym pobieraniu przeglądarki. Obsługa obrazów jako tekstu również upraszcza rzeczy, gdy musisz wysyłać / odbierać json, co nie obsługuje zbyt dobrze plików binarnych.
Tak, rozumiem, że możesz przechowywać plik binarny w bazie danych i konwertować go do / z tekstu podczas wchodzenia i wychodzenia z bazy danych, ale czasami ORMy sprawiają, że jest to kłopotliwe. Może być prostsze traktowanie go jako prostego tekstu, tak jak wszystkie inne pola.
To zdecydowanie właściwy sposób postępowania z miniaturami.
(Obrazy OP nie są małe, więc nie jest to odpowiedź na jego pytanie.)
źródło