większość systemów bazodanowych zapewnia typ danych, który może przechowywać dane surowe, a PostgreSQL nie jest wyjątkiem. Używam terminu surowych danych, aby oznaczać, że baza danych nie rozumie struktury ani znaczenia wartości. Natomiast PostgreSQL rozumie strukturę i znaczenie innych typów danych. Na przykład, gdy definiujesz kolumnę INTEGER, PostgreSQL wie, że bajty danych, które umieszczasz w tej kolumnie, mają reprezentować wartość całkowitą. PostgreSQL wie co to jest liczba całkowita?może dodawać liczby całkowite, mnożyć je, konwertować je do i z postaci ciągu, i tak dalej. Z drugiej strony, surowe dane to tylko zbiór bitów?PostgreSQL nie może wywnioskować żadnego znaczenia w danych.

PostgreSQL oferuje Typ BYTEA do przechowywania surowych danych. Kolumna BYTEA może teoretycznie zawierać wartości o dowolnej długości, ale wydaje się, że maksymalna długość wynosi 1 GB.

rozmiar wartości bajtu wynosi 4 bajty plus rzeczywista liczba bajtów w wartości.

składnia dla wartości dosłownych

wprowadzenie wartości bajtowej może być trochę trudne. Literał bajtowy jest wprowadzany jako literał Łańcuchowy: jest to tylko ciąg znaków zamknięty w pojedynczych cudzysłowach. Biorąc to pod uwagę, jak wprowadzić wartość BYTEA, która zawiera pojedynczy cudzysłów? Jeśli spojrzysz wstecz na omówienie wartości literalnych ciągów znaków (wcześniej w tym rozdziale), zobaczysz, że możesz dodać znaki specjalne do wartości ciągu znaków, unikając ich. W szczególności pojedynczy cytat może być przez uniknięcie na jeden z trzech sposobów:

  • podwojenie pojedynczych cytatów („to jest pojedynczy cytat”’)

  • poprzedzić pojedynczy cytat odwrotnym ukośnikiem („jest to pojedynczy cytat \”)

  • zamiast tego należy podać wartość ósemkową znaku („jest to pojedynczy cytat \047′)

istnieją jeszcze dwa inne znaki, które należy usunąć podczas wprowadzania literałów bajtowych. Bajt, którego wartość jest równa zero (nie znak 0, ale bajt null) musi być znakiem zabezpieczającym, a znak odwrotnego ukośnika musi być znakiem zabezpieczającym. Możesz uciec dowolny znak używając formy „\\DDD ” (gdzie ddd jest liczbą ósemkową). Za pomocą formularza „\\C” można usunąć dowolny znak drukowany. Tak więc, jeśli chcesz zapisać wartość BYTEA, która zawiera bajt zerowy, możesz wprowadzić ją w ten sposób:

'This is a zero byte \000'

jeśli chcesz zapisać wartość BYTEA zawierającą ukośnik wsteczny, możesz wprowadzić ją w jednej z następujących form:

'This is a backslash \\''This is also a backslash \134'

jeśli porównasz te reguły z regułami cytowania literałów łańcuchowych, zauważysz, że literały BYTEA wymagają dwa razy więcej znaków odwrotnego ukośnika. Jest to dziwactwo konstrukcji parsera PostgreSQL. Literały BYTEA są przetwarzane przez dwa różne parsery. Główny parser PostgreSQL widzi literał bajtowy jako literał Łańcuchowy (pochłania pierwszy zestaw znaków odwrotnego ukośnika). Następnie parser BYTEA przetwarza wynik, pochłaniając drugi zestaw znaków odwrotnego ukośnika.

więc, jeśli masz wartość BYTEA, taką jak to jest odwrotnym ukośnikiem \, cytujesz ją jako ’ to jest odwrotnym ukośnikiem \\\\’. Po przetworzeniu tego ciągu przez parser łańcuchów, został on zamieniony na ’ This is A backslash \\’. Parser BYTEA ostatecznie przekształca to w to jest odwrotnym ukośnikiem \.

obsługiwane operatory

PostgreSQL oferuje jeden operator BYTEA: concatenation. Można dodać jedną wartość BYTEA do innej wartości BYTEA za pomocą operatora concatenation ( | / ).

zauważ, że nie możesz porównać dwóch wartości BYTEA, nawet dla równości/nierówności. Można oczywiście przekształcić wartość BYTEA na inną wartość za pomocą operatora CAST (), co otwiera inne operatory.

Large-Objects

typ danych BYTEA jest obecnie ograniczony do przechowywania wartości nie większych niż 1 GB. Jeśli chcesz przechowywać wartości większe niż zmieści się w kolumnie BYTEA, możesz użyć large-objects. Duży obiekt jest wartością przechowywaną poza tabelą. Na przykład, jeśli chcesz zapisać zdjęcie z każdym wierszem w tabeli taśm, Dodaj kolumnę OID, aby zachować odniesienie do odpowiedniego dużego obiektu:

movies=# ALTER TABLE tapes ADD COLUMN photo_id OID;ALTER

każda wartość w kolumnie photo_id odnosi się do wpisu w tabeli systemowej pg_largeobject. PostgreSQL udostępnia funkcję, która załaduje zewnętrzny plik (taki jak plik JPEG) do tabeli pg_largeobject:

movies=# INSERT INTO tapes VALUESmovies-# (movies(# 'AA-55892',movies(# 'Casablanca',movies(# lo_import('/tmp/casablanca.jpg' )movies(# );

funkcja lo_import() ładuje nazwany plik do pg_largeobject i zwraca wartość OID odnoszącą się do dużego obiektu. Teraz po wybraniu tego wiersza zobaczysz identyfikator OID, a nie rzeczywiste fragmenty składające się na zdjęcie:

movies=# SELECT * FROM tapes WHERE title = 'Casablanca'; tape_id | title | photo_id----------+------------+---------- MC-68873 | Casablanca | 510699

jeśli chcesz zapisać zdjęcie z powrotem do pliku, możesz użyć funkcji lo_export() :

movies=# SELECT lo_export( 510699, '/tmp/Casablanca.jpg' ); lo_export----------- 1(1 row)

aby zobaczyć wszystkie duże obiekty w bieżącej bazie danych, użyj PSQL \ lo_list metacommand:

movies=# \lo_list Large objects ID | Description--------+------------- 510699 |(1 row)

możesz usunąć duże obiekty z bazy danych za pomocą funkcji lo_unlink() :

movies=# SELECT lo_unlink( 510699 ); lo_unlink----------- 1(1 row)movies=# \lo_list Large objects ID | Description----+-------------(0 rows)

jak dostać się do rzeczywistych bitów za referencyjnym OID? Nie możesz?przynajmniej nie z psql. Obsługa dużych obiektów musi być wbudowana w używaną aplikację kliencką. psql jest narzędziem zorientowanym na tekst i nie ma możliwości wyświetlania zdjęcia, więc najlepiej jest spojrzeć na surowe dane w tabeli pg_largeobject. Kilka aplikacji klienckich, takich jak Conjectrix Workstation, obsługuje duże obiekty i w większości przypadków może poprawnie interpretować surowe dane.