2012-03-07 20 views

Odpowiedz

39

Masz zasadniczo dwie możliwości. Możesz przechowywać dane bezpośrednio w rzędzie lub możesz użyć obiektu dużego obiektu. Ponieważ PostgreSQL teraz używa czegoś o nazwie TOAST, aby przenieść duże pola poza tabelę, nie powinno być kary za wydajność związanej z przechowywaniem dużych danych bezpośrednio w wierszu. Pozostaje 1 GB limitu rozmiaru pola. Jeśli jest to zbyt ograniczone lub jeśli chcesz korzystać z API strumieniowania, możesz skorzystać z obiektu o dużych obiektach, który daje ci coś w rodzaju deskryptorów plików w bazie danych. Przechowujesz identyfikator LO w kolumnie i możesz odczytać i zapisać z tego identyfikatora.

Osobiście sugeruję unikanie obiektu dużego obiektu, chyba że jest to absolutnie konieczne. W przypadku TOAST większość przypadków użycia dotyczy tylko korzystania z bazy danych w sposób zgodny z oczekiwaniami. W przypadku dużych obiektów, ponosisz dodatkowe obciążenia konserwacyjne, ponieważ musisz śledzić używane identyfikatory LO i pamiętać o rozłączeniu ich, gdy nie są już używane (ale nie wcześniej) lub zasiądą w katalog danych zajmujący miejsce na zawsze. Istnieje również wiele udogodnień, które mają wyjątkowe zachowanie wokół nich, których szczegóły uciekają mi, ponieważ nigdy ich nie używam.

Dla większości ludzi, duża kara za wydajność związana z przechowywaniem dużych danych w bazie danych jest taka, że ​​oprogramowanie ORM wyciągnie duże dane z każdego zapytania, chyba że wyraźnie zaleci się, aby tego nie robił. Powinieneś zadbać, aby powiedzieć Hibernate'owi lub cokolwiek innego, czego używasz, aby traktować te kolumny jako duże i pobierać je tylko wtedy, gdy jest to wymagane.

+0

Dobra odpowiedź, bardzo dziękuję. Czy typ bajtów służy do przechowywania zawartości w tabeli? –

+2

dane bytea będą przechowywane domyślnie w tabeli, jeśli są małe i przeniesione do tabeli pomocniczej ("toast") i skompresowane dla większych wartości. Zobacz: http://www.postgresql.org/docs/9.1/static/storage-toast.html w celu wprowadzenia. Możesz wyłączyć kompresję pamięci dyskowej, co poprawi wydajność pobierania tylko części wartości. – araqnid

+0

'bytea' jest dobrym wyborem dla danych binarnych. Możesz także użyć 'text' lub' varchar', jeśli dane są tekstowe i mają takie samo kodowanie jak baza danych. –

8

Typ BLOB (LO) przechowuje dane w porcjach 2 KB w standardowej stronie sterty PostgreSQL, która domyślnie ma rozmiar 8 KB. Nie są przechowywane jako niezależne, spójne pliki w systemie plików - na przykład nie można zlokalizować pliku, porównać bajt po bajcie i oczekiwać, że będzie taki sam jak oryginalne dane pliku, które ładowane do bazy danych, ponieważ istnieją również nagłówki i struktury stron Postgresów, które określają porcje.

Należy unikać używania interfejsu Large Object (LO), jeśli aplikacja wymagałaby częstej aktualizacji danych binarnych, a zwłaszcza jeśli wymagała dużej liczby drobnych zapisów o dostępie swobodnym, co wynika ze sposobu, w jaki PostgreSQL implementuje współbieżność kontrola (MVCC) może prowadzić do eksplozji w ilości miejsca na dysku używanego, dopóki nie odłączysz bazy danych. Ten sam wynik prawdopodobnie dotyczy również danych przechowywanych w linii w kolumnie o typie bytea lub nawet TOAST'd.

Jeśli jednak dane są zgodne z wzorcem "pisz raz, czytaj-wiele" (np. Prześlij obraz PNG i nigdy go nie modyfikuj), powinno być dobrze z punktu widzenia użycia dysku.

Aby uzyskać dalszą dyskusję, zobacz temat this pgsql-general mailing list thread.

Powiązane problemy