Jakie jest najlepsze miejsce do przechowywania plików binarnych związanych z danymi w bazie danych? Powinieneś:
- Przechowuj w bazie danych z obiektu blob
- Przechowuj w systemie plików z linkiem w bazie danych
- Przechowuj w systemie plików, ale zmień nazwę na skrót zawartości i zapisz skrót w bazie danych
- Coś, o czym nie myślałem
Zaletą (1) jest (między innymi) to, że zachowana jest atomowość transakcji. Koszt polega na tym, że możesz radykalnie zwiększyć wymagania dotyczące przestrzeni dyskowej (i związane z nią wymagania dotyczące przesyłania / tworzenia kopii zapasowych)
Celem (3) jest do pewnego stopnia zachowanie atomowości - jeśli możesz wymusić, że system plików, do którego piszesz, nie pozwala na zmianę lub usunięcie plików i zawsze ma poprawny skrót jako nazwę pliku. Pomysł polegałby na zapisaniu pliku w systemie plików przed zezwoleniem na wstawienie / aktualizację odnoszącą się do skrótu - jeśli transakcja zakończy się niepowodzeniem po zapisie systemu plików, ale przed DML bazy danych, to dobrze, ponieważ system plików „fałszuje” będący repozytorium wszystkich możliwe pliki i skróty - nie ma znaczenia, czy są tam jakieś pliki, które nie są wskazywane (i możesz je okresowo czyścić, jeśli jesteś ostrożny)
EDYTOWAĆ:
Wygląda na to, że niektóre RDBMS mają to na swój sposób - chciałbym wiedzieć, jak robią to inni - a zwłaszcza rozwiązanie dla postgres
źródło
Odpowiedzi:
Przechowuj w bazie danych z obiektu blob
Wadą jest to, że sprawia, że pliki bazy danych są dość duże i być może zbyt duże, aby wykonać kopię zapasową w istniejącym zestawie. Zaletą jest integralność i atomowość.
Przechowuj w systemie plików z linkiem w bazie danych
Natrafiłem na takie straszne katastrofy i przeraża mnie to, że ludzie ciągle to sugerują. Niektóre z katastrof to:
C:\
końca do.doc
i nie wszystkie wersje NT były w stanie poradzić sobie z długimi ścieżkami.Przechowuj w systemie plików, ale zmień nazwę na skrót zawartości i zapisz skrót w bazie danych
Ostatnie miejsce, w którym pracowałem, zrobiło to na podstawie mojego wyjaśnienia powyższych scenariuszy. Uważali, że jest to kompromis między niezdolnością organizacji do zdobycia doświadczenia z dużymi bazami danych (wszystko większe niż około 40G zostało uznane za „zbyt duże”), niezdolnością korporacyjną do zakupu dużych dysków twardych, a niezdolnością do zakupu bardziej nowoczesnego zaplecza rozwiązania i potrzebę uniknięcia ryzyka nr 1 i 3, które zidentyfikowałem powyżej.
Moim zdaniem przechowywanie w bazie danych jako obiektu blob jest lepszym rozwiązaniem i bardziej skalowalne w scenariuszu z wieloma serwerami, szczególnie w przypadku problemów z przełączaniem awaryjnym i dostępnością.
źródło
Numer 1 dla całkowitej integralności danych. Użyj innych opcji, jeśli nie zależy Ci na jakości danych. To takie proste.
Większość RDBMS ma i tak optymalizacje do przechowywania BLOBów (np. Strumień plików SQL Server)
źródło
Jeśli wybierasz wyrocznię, spójrz na dbfs i Secure Files.
Bezpieczne pliki mówi wszystko, chroń WSZYSTKIE swoje dane w bazie danych. Jest zorganizowany w płaty. Bezpieczne pliki to zmodernizowana wersja lobów, którą należy aktywować.
dbfs to system plików w bazie danych. Możesz zamontować go podobnie jak sieciowy system plików na hoście Linux. To jest naprawdę potężne. Zobacz blog Ma również wiele opcji dostosowywania do konkretnych potrzeb. Będąc dba, mając system plików (oparty na bazie danych, zamontowany na Linuksie), stworzyłem na nim bazę danych Oracle bez żadnych problemów. (baza danych przechowywana w ... bazie danych). Nie byłoby to bardzo przydatne, ale pokazuje moc.
Inne zalety to: dostępność, tworzenie kopii zapasowych, odzyskiwanie, wszystko odczytywane zgodnie z innymi danymi relacyjnymi.
Czasami rozmiar podaje się jako powód, dla którego nie należy przechowywać dokumentów w bazie danych. Należy prawdopodobnie wykonać kopię zapasową tych danych, więc nie jest to dobry powód, aby nie przechowywać w bazie danych. Zwłaszcza w sytuacji, gdy stare dokumenty należy traktować jako tylko do odczytu, duże części bazy danych można łatwo odczytać. W takim przypadku te części bazy danych nie wymagają już częstej kopii zapasowej.
Odwołanie w tabeli do czegoś spoza bazy danych jest niebezpieczne. Można nim manipulować, jest trudny do sprawdzenia i łatwo się zgubić. A co z transakcjami? Baza danych oferuje rozwiązania wszystkich tych problemów. Dzięki Oracle DBFS możesz przekazywać swoje dokumenty aplikacjom innym niż bazy danych, a one nawet nie wiedziały, że włamują się do bazy danych.
Ostatnia wielka niespodzianka: wydajność systemu plików dbfs jest często lepsza niż zwykłego systemu plików. Jest to szczególnie ważne, jeśli pliki są większe niż kilka bloków.
źródło
Myślę, że właściwa odpowiedź zależy w dużej mierze od twojej aplikacji i tego, jak ważne są te dokumenty.
W przypadku systemu zarządzania dokumentami lub systemu, w którym odzyskiwanie przechowywanych dokumentów ma kluczowe znaczenie (więc większość rzeczy związanych z finansami, zasobami ludzkimi lub CRM), przechowywanie dokumentów w trybie online lub korzystanie z zastrzeżonej technologii dokumentów twojego ulubionego dostawcy DB wydaje się być właściwą rzeczą do zrobienia.
Istnieje jednak wiele aplikacji, w których uważam, że przeciwna decyzja jest właściwa.
Systemy pomocy technicznej i systemy typu wiki to takie, w których myślę, że sensowne jest trzymanie danych poza bazą danych. Uważam, że niektórzy, jak Jira, faktycznie oferują opcję wyboru, czy dokumenty mają być przechowywane w tekście, czy nie.
W przypadku średnich firm przechowywanie dokumentów w systemie biletów wewnętrznych może oznaczać różnicę między skompresowaną kopią zapasową mierzoną w megabajtach a kopią zapasową mierzoną w gigabajtach.
Osobiście wolałbym przywrócić system biletowy do sieci w ciągu kilku minut i zmagać się z (ogólnie mniej ważnymi) dokumentami przez kilka godzin, niż zwiększyć mój „jest zepsuty, a CTO oddycha mi po szyi” RTO przez przywrócenie i odtwarzaj logi ze znacznie większej kopii zapasowej.
Istnieją inne zalety oddzielenia dokumentów.
Myślę, że hybrydowa kombinacja # 2 i # 3 może być sprytna. Zachowaj oryginalne nazwy plików, ale oblicz i przechowuj skrót / sumę kontrolną dokumentu, aby mieć punkt odniesienia, który pomoże odzyskać w przypadku przeniesienia lub zmiany nazwy pliku.
Przechowywanie plików z oryginalnymi nazwami plików oznacza, że aplikacje mogą dosłownie szarpać je bezpośrednio z systemu plików i wysyłać je przewodowo lub w gęstym świecie klientów, może nawet skierować użytkownika bezpośrednio do serwera plików.
źródło
Nie rób tego
Naprawdę nie ma plusu przechowywania plików w bazie danych.
Czy to już nie jest dziwne i podejrzane, gdy myślisz:
Nawet lepiej, powiedz to na głos.
Do faktów:
Korzystanie z bazy danych
„ PROS ” ... ale niezupełnie :
Naprawdę nie chcę być stronniczy, ale nie sądzę, aby było coś więcej do dodania. Zalety nie są tak świetne, jeśli się nad tym zastanowić.
Jeśli zapomniałem czegoś o komentarzu poniżej, w międzyczasie czytaj dalej poniżej.
CONS:
Korzystanie z systemu plików
Plusy:
Wady :
*Drobnym drukiem
W tej chwili zadajesz sobie pytanie, nie przejmuj się ?! Dlaczego?
Największe błędy tutaj polegają na tym, że ludzie próbują wkręcić śrubę młotkiem.
Głównym powodem i chciałbym powiedzieć, że jedynym powodem, dla którego jest o to pytany, są linki plików .
Jest to problem, którego nie ma rozwiązać baza danych. Brzmi nawet głupio, jeśli się nad tym zastanowić.
W rzeczywistości, logicznie, aplikacja powinna faktycznie zajmować się obsługą i udostępnianiem linków.
Rozwiązanie:
Spowodowałoby to również oderwanie natywnych ścieżek, uczyniłoby aplikację bardziej przenośną, łatwą w utrzymaniu i pozwalało na przełączanie się na dowolny system plików bez niszczenia czegokolwiek.
Jeśli chodzi o sposób implementacji, wykracza to poza zakres tej odpowiedzi, ale możesz rzucić okiem na ogólny przykład w prawdopodobnie najczęściej używanym języku internetowym (PHP):
https://github.com/symfony/Routing
https://github.com/kriswallsmith/assetic
Oba razem są naprawdę potężne.
źródło
Chcę tu dodać moje doświadczenie dotyczące kompromisów. W PostgreSQL przynajmniej wpływ na wydajność jest dość minimalny pod względem serwera db. Duże obiekty BLOB są przechowywane w osobnych plikach, a nie w głównych tabelach sterty, aby usunąć je z drogi operacji, które mogą liczyć dużą liczbę rekordów. Inne dbs mogą zrobić coś podobnego.
Główną zaletą jest możliwość przechowywania wszystkich powiązanych danych w jednym miejscu w celu zachowania atomowości i tworzenia kopii zapasowych. To znacznie zmniejsza ryzyko, że coś pójdzie nie tak.
Główną wadą nie jest to, co widziałem powyżej, a to użycie pamięci w interfejsie. Nie wiem dokładnie, jak radzi sobie z tym każdy db, więc może to zależeć od implementacji, ale w przypadku PostgreSQL dane są wprowadzane jako ciąg znaków ASCII ze znakiem ucieczki (być może w systemie szesnastkowym, ewentualnie z wstawionymi znakami ucieczki). Następnie należy go przekonwertować z powrotem na binarny w interfejsie użytkownika. Wiele frameworków, które widziałem, aby to robić, wymaga przekazania wartości (a nie odniesienia), a następnie zbudowania nowego ciągu binarnego na jej podstawie. Obliczyłem, że użycie Perla do zrobienia tego przyniosło wielokrotne użycie pamięci oryginalnego pliku binarnego.
Werdykt: Jeśli dostęp do plików jest tylko okazjonalny, zapisałbym w db. Jeśli są one często i wielokrotnie dostępne, przynajmniej za pomocą PostgreSQL, myślę, że koszty przewyższają korzyści.
źródło
Wcześniej Microsoft przełożył się na możliwość przechowywania obrazów (i podobnych typów danych obiektów blob) w bazie danych. To była świetna nowa funkcja programu SQL Server 2000 (jestem prawie pewien, że był to 2000, a nie 7.0) i wiele osób wskoczyło na modę.
Przechowywanie BLOBS w bazie danych ma zalety i wady:
Z jednej strony wszystkie dane i powiązane obrazy lub dokumenty mogą być przechowywane i dostępne w jednym miejscu. Użytkownik aplikacji nie wymaga specjalnych uprawnień sieciowych, ponieważ to SQL obsługuje obrazy / pliki / dokumenty.
Z drugiej strony twoja baza danych może rosnąć dość duża, w zależności od wielkości i liczby przechowywanych BLOBÓW. Wpływa to na kopie zapasowe, wymagania dotyczące miejsca, operacje odzyskiwania zależne od czasu itp.
SQL Server 2008 wprowadził streaming plików. Baza danych zawiera wskaźniki do plików, pliki znajdują się na serwerze nie w bazie danych, ale podczas tworzenia kopii zapasowej bazy danych są również tworzone kopie zapasowe.
Twoje kopie zapasowe mogą być dość duże, ale nie kończysz się na osieroconych plikach / dokumentach / obiektach blob / obrazach.
Osobiście wolałem, aby baza danych przechowywała wskaźniki / lokalizacje sieciowe i pozwalała serwerowi plików obsługiwać pliki. Serwery plików i tak są lepiej zoptymalizowane do takich zadań.
źródło
SELECT image FROM table
w SSMS i sprawdzasz, czy jest odpowiedni obraz?Nie przechowuj plików w bazie danych.
Każdy, bez wyjątku, który może uruchomić dowolny RDBMS na rynku, ma już bazę danych do przechowywania plików, a sama RDBMS z niej korzysta! Ta baza danych to system plików . Porozmawiajmy teraz o niektórych potencjalnych wadach przechowywania plików w bazie danych, a także o niektórych konkretnych czynnikach ograniczających ryzyko przechowywania plików w bazie danych.
Brak uchwytów plików do plików w bazie danych. Co to znaczy?
Programator-talk: NIE MOŻESZ szukać (
fseek
), nie ma możliwości zarządzania zasobem z dostępem asynchronicznym (asyncio
lubepoll
), nie masendfile
(zapisywanie kopii z miejsca jądra).Praktyczne zastosowanie: chcesz wysłać wideo lub zdjęcie do klienta przez HTTP2 / 3? Jeśli jest w bazie danych, najpierw musisz go zapytać. Aby każde zapytanie zwróciło ten plik, musisz poczekać na zakończenie całego zapytania, zanim plik będzie mógł przejść do następnego kroku. W instalacji produkcyjnej z rdbms na innym serwerze niż serwer WWW, najpierw musisz przenieść plik w całości z rdbms na serwer WWW, zamiast przesyłać go strumieniowo. Jeśli jednak warstwa transportowa zapewnia abstrakcję systemu plików (którą obsługuje nawet NFS), możesz przeszukać plik w połowie i natychmiast rozpocząć przesyłanie strumieniowe z powrotem do klienta bez buforowania większej ilości pliku niż to konieczne. Jest to rutynowo wykonywane przez serwer WWWnginx , Apache , PureFTP i ProFTP.
Podwójna kopia na RDBMS. Sam fakt, że znajduje się w bazie danych, prawdopodobnie spowoduje, że napiszesz go dwa razy. Raz w dzienniku z wyprzedzeniem zapisu (WAL), a następnie ponownie w obszarze tabel.
Brak aktualizacji, kiedykolwiek MVCC oznacza, że nic się nie aktualizuje, tylko kopiowane na nowo z modyfikacjami, a następnie stary wiersz jest oznaczany jako wygasły (usunięty). Każda aktualizacja pliku będzie wymagać zapisania całego wiersza , a nie tylko pliku całego wiersza. Systemy plików mogą to również zapewniać z rejestrowaniem danych, ale rzadko jest to potrzebne.
Odczytywanie i przesyłanie plików w celu spowolnienia zapytania Jeśli sam plik jest przechowywany w wierszu, który należy wykonać zapytanie, cały wiersz albo będzie musiał poczekać na przesłanie pliku, albo będziesz musiał wydać dwa oddzielne zapytania .
Wykorzystanie pamięci na kliencie DB. Klient DB (libpq, jdbc, odbc, freetds itp.) Lub podobny prawdopodobnie buforuje zapytanie w pamięci. Kiedy bufor w pamięci zostanie wyczerpany, może uruchomić bufor dysku lub, co gorsza, może spaść z powrotem do jądra, aby zostać przywołany na dysk.
Ograniczanie zapytań w wielu bazach danych umożliwia zabijanie i zbieranie zapytań, gdy zajmują one zbyt wiele czasu lub zasobów. Pamiętaj, że transfery plików w żadnej implementacji nie zostaną wyszczególnione. Czy to zapytanie zostało zabite po 3 sekundach? A może zajęło to 1 sekundę, a backend poświęcił 2 sekundy na przesłanie pliku? Nie tylko „wyszczególnione”, w jaki sposób zamierzasz skutecznie określić, ile czasu powinno zająć zapytanie, gdy 99,9% zapytań zwraca 1 KB, a drugie zwraca 1 GB?
XFS i BTRFS bez kopiowania przy zapisie lub deduplikacji obsługują przezroczyste kopiowanie przy zapisie i usuwanie duplikatów. Oznacza to, że posiadanie wszędzie tego samego obrazu lub potrzeba jego drugiej kopii może być w przejrzysty sposób obsługiwane przez system plików. Jeśli jednak plik nie stoi sam i znajduje się w wierszu lub w sklepie, system plików prawdopodobnie nie będzie w stanie go deduplikować.
Uczciwość Wiele osób mówi tutaj o uczciwości. Jak myślisz, co może być lepszego w wykrywaniu uszkodzeń systemu plików, aplikacji korzystającej z systemu plików lub podstawowych narzędzi systemu plików? Przechowuj plik w wierszu lub poza linią, a wszelkie uszkodzenia systemu plików będą zaciemniać bazę danych.
xfs_repair
jest cholernie dobry w odzyskiwaniu, gdy masz uszkodzenie systemu plików lub dysku twardego, a jeśli zawiedzie, nadal będzie o wiele łatwiej robić kryminalistykę danych.Migracja w chmurze, jeśli kiedykolwiek chcesz przechowywać pliki w sieci SAN lub w chmurze, tym bardziej będziesz mieć trudności, ponieważ teraz migracja pamięci jest migracją bazy danych. Jeśli twoje pliki są na przykład przechowywane w systemie plików, możesz dość łatwo przenieść je do S3 (a przy czym coś takiego
s3fs
może być przezroczyste).Wyjątki
Przechowywanie plików w bazie danych ma kilka ważnych przypadków użycia,
Łagodzenie
Niektóre bazy danych mają pojęcie „zasobu zarządzanego zewnętrznie”, w którym baza danych zarządza prywatnie plikiem na dysku, takim jak
PostgreSQL za pośrednictwem infrastruktury dużych obiektów zapewnia uchwyt pliku do zasobu na czas trwania transakcji.
Infrastruktura strumienia plików programu SQL Server 2017 zapewnia tymczasowy dostęp na czas trwania transakcji, którego można użyć do uzyskania ścieżki pliku i otwarcia uchwytu pliku.
Oracle zapewnia
BFILE
(nie ma to nic wspólnego z wewnętrznymi obiektami LOB, które są nazywaneSecureFile
Niektóre bazy danych przechowują duże obiekty binarne poza linią lub mogą, na przykład Oracle SecureFile. Umożliwia to aktualizację wiersza bez przepisywania pliku.
Niektóre bazy danych, takie jak Oracle, wykonują MVC bez dziennika WAL i nie muszą dwukrotnie zapisywać pliku.
Niektóre bazy danych, takie jak SQL Server i Oracle, umożliwiają „przesyłanie strumieniowe” danych z pliku bez konieczności posiadania dojścia do pliku. To może, ale nie musi, działać przy innym połączeniu niż zapytanie do baz danych. Ale najważniejsze jest to, że podczas gdy można przesyłać plik (w teorii), nie mogę znaleźć żadnych dowodów jakiegokolwiek produktu nie dokonane przez dostawcę, który używa tej funkcji. Na przykład, gdzie jest most NGINX / Apache, aby ci to umożliwić?
Oracle zapewnia opcjonalną deduplikację, kompresję i szyfrowanie poprzez pamięć wewnętrzną LOB (jak SecureFile).
Wniosek
Najgorszy scenariusz po umieszczeniu pliku w bazie danych jest bardzo zły pod względem wydajności i zgodności z narzędziami. Zawsze jest wyjątkowo zależne od implementacji. W żaden sposób baza danych nie jest lepszym systemem plików niż system plików. Pod każdym względem jest to kompromis, a nawet gdy otrzymasz potężne funkcje łagodzące (jak w przypadku SecureFile), narzędzia są tak słabe, że tak naprawdę nie są niczym więcej niż punktem marketingowym, chyba że cały stos jest zbudowany przez dostawcę RDBMS.
Uprość to, a ogólną zasadą jest trzymanie plików z dala od bazy danych .
Rozwiązanie
Jak należy przechowywać pliki lub wyodrębnić system plików w taki sposób, aby skutecznie działać dla wielu najemców i użytkowników? Jestem stronniczy od mieszania zawartości pliku. Obecnie jest to dość powszechne i działa dobrze.
źródło
Chociaż częściowo zależy to od aplikacji / środowiska (w tym osób), wybrałbym obiekt blob.
Przechowywanie wszystkiego w bazie danych oznacza, że replikacja działa dla danych plików. Potrzebny byłby osobny mechanizm do synchronizacji plików FS.
W niektórych aplikacjach system plików i tak nie powinien być modyfikowany. Na przykład na stronie produkcyjnej unikałbym używania systemu plików do jakichkolwiek danych jednorazowych (strona żyje pod SCM, dane w bazie danych).
Zakładając, że mamy wielu użytkowników / aplikacje z osobnymi uprawnieniami, wówczas dowolna pamięć systemu plików daje możliwość różnic w prawach dostępu do bazy danych i bazy danych.
Udoskonaleniem, jakie rozważam w zakresie przechowywania BLOB, jest fragmentowanie danych, jeśli ma to sens; jeśli potrzebujesz tylko 512 bajtów z 20-MB BLOB, ten sektorowy dostęp jest prawdziwym dobrodziejstwem, szczególnie jeśli masz do czynienia ze zdalnymi klientami (i ponownie, częściowa aktualizacja powoduje znacznie mniejszy ruch replikacji).
źródło
Mój głos nie byłby na żaden. Przechowuj dane w systemie takim jak Amazon S3 lub CDN Microsft i przechowuj ten adres URL w bazie danych.
W ten sposób zyskujesz pewność, że dane są zawsze dostępne bez konieczności dysponowania bazami danych wielkości potwora.
źródło
Dla postgres:
To jest rzeczywiście proste. Istnieje
BYTEA
typ, którego można używać do przechowywania ciągów binarnych. Domyślnie nie ma wbudowanych narzędzi takich jak te wymienione dla MS lub Oracle. Przechowywanie wielu dużych plików i ich odzyskiwanie może być nudne. Musisz także dokonać konwersji plików w aplikacji (np. ZByteStream
podobnym lub podobnym, nie mam pojęcia, jak to działa z konkretnymi rozwiązaniami baz danych </> dla plików MS / Oracle). Istnieje równieżlo
typ, który pomaga w pracy z zarządzaniem BLOBami, ponieważ niektóre wewnętrzne zarządzanie tymi typami może nie śledzić referencji.źródło
Podziel się moim doświadczeniem z serwerem Ms SQL i ogromną liczbą plików. Zapisujemy pliki na serwerze plików. Baza danych ma dwie tabele, jedną dla folderów plików i poświadczeń dostępu, jedną dla nazwy pliku. Baza danych i pliki są łatwe w utrzymaniu. Możesz łatwo przenosić pliki nawet na serwerach, wystarczy zmodyfikować tabelę folderów.
źródło