SQL, OID Postgres, czym są i dlaczego są przydatne?

161

Patrzę na tworzenie niektórych tabel PostgreSQL i natknąłem się na to:

CREATE TABLE (
...
) WITH ( OIDS = FALSE );

Przeczytałem dokumentację dostarczoną przez postgres i znam koncepcję identyfikatora obiektu z OOP, ale nadal nie rozumiem,

  • dlaczego taki identyfikator miałby być przydatny w bazie danych?
  • skrócić zapytania?
  • kiedy należy go używać?
fabrizioM
źródło
W tej chwili nie mogę znaleźć żadnych odniesień do zacytowania, ale do Twojej wiadomości słyszałem, że użycie Microsoft Access jako interfejsu użytkownika Postgres wymaga obecności oldkolumny systemowej .
Basil Bourque

Odpowiedzi:

165

Identyfikatory OID w zasadzie dają wbudowany, globalnie unikalny identyfikator dla każdego wiersza, zawarty w kolumnie systemowej (w przeciwieństwie do kolumny przestrzeni użytkownika). Jest to przydatne w przypadku tabel, w których nie masz klucza podstawowego, masz zduplikowane wiersze itp. Na przykład, jeśli masz tabelę z dwoma identycznymi wierszami i chcesz usunąć najstarszy z nich, możesz to zrobić za pomocą kolumna oid.

Z mojego doświadczenia wynika, że ​​ta funkcja jest generalnie nieużywana w większości aplikacji wspieranych przez postgres (prawdopodobnie częściowo dlatego, że są niestandardowe), a ich użycie jest zasadniczo przestarzałe :

W PostgreSQL 8.1 default_with_oids jest domyślnie wyłączone; we wcześniejszych wersjach PostgreSQL był on domyślnie włączony.

Użycie identyfikatorów OID w tabelach użytkowników jest uważane za przestarzałe, dlatego w większości instalacji należy pozostawić tę zmienną wyłączoną. Aplikacje wymagające identyfikatorów OID dla określonej tabeli powinny podczas tworzenia tabeli określić opcję WITH OIDS. Tę zmienną można włączyć w celu zapewnienia zgodności ze starymi aplikacjami, które nie obsługują tego zachowania.

Frank Farmer
źródło
33
nie ma gwarancji, że są one niepowtarzalne. Z dokumentów: „W dużej lub długowiecznej bazie danych licznik może się zawijać. Dlatego złą praktyką jest zakładanie, że identyfikatory OID są unikalne, chyba że podejmiesz kroki w celu zapewnienia, że ​​tak jest.”
radiospiel
8
Zawijanie oznacza również, że niekoniecznie można było usunąć starszy z dwóch wierszy tylko na podstawie ich OID, ponieważ ten z niższym OID mógł być zawijany.
Carl G
OID nie są unikalne w skali globalnej, zgodnie z powyższym komentarzem, ani też nie były w 2011 roku, kiedy napisano tę odpowiedź. Ponadto identyfikatory OID są potrzebne dla obiektów systemowych, więc wykorzystanie wszystkich OID w licznikach wierszy nie pomaga bazie danych w przypisywaniu OID do nowych tabel (dla tabeli, a nie jej wierszy). Zastanów się także, czy pojedynczy licznik 4-bajtowych liczb całkowitych będzie naprawdę wystarczający dla każdej tabeli w Twojej bazie danych.
FuzzyChef
warto wspomnieć, że w większości implementacji phpPgAdmina podczas tworzenia tabeli zaznaczona jest opcja wyłącz domyślnie, co oznacza w rzeczywistości, że ta opcja jest przestarzała.
vdegenne
3
jeśli nie wiesz, do czego służą OIDy, prawdopodobnie nie chcesz ich używać.
vdegenne
16

OIDy są nadal używane dla Postgres z dużymi obiektami (chociaż niektórzy ludzie twierdzą, że duże obiekty i tak nie są ogólnie przydatne). Są również szeroko wykorzystywane w tabelach systemowych . Są używane na przykład przez TOAST, który przechowuje większe niż 8KB BYTEA (itp.) W oddzielnym obszarze przechowywania (przezroczystym), który jest używany domyślnie przez wszystkie tabele . Ich bezpośrednie użycie związane z „normalnymi” tabelami użytkowników jest zasadniczo przestarzałe .

Typ oid jest obecnie zaimplementowany jako czterobajtowa liczba całkowita bez znaku. Dlatego nie jest wystarczająco duży, aby zapewnić wyjątkowość całej bazy danych w dużych bazach danych, a nawet w dużych pojedynczych tabelach. Dlatego nie zaleca się używania kolumny OID tabeli utworzonej przez użytkownika jako klucza podstawowego. Identyfikatorów OID najlepiej używać tylko w przypadku odwołań do tabel systemowych.

Najwyraźniej sekwencja OID „zawija się”, jeśli przekracza 4B 6 . W istocie jest to globalny licznik, który może się zawijać. Jeśli się zawija, może zacząć występować spowolnienie, gdy jest używane i „wyszukiwane” w poszukiwaniu unikalnych wartości itp.

Zobacz także https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

rogerdpack
źródło
9

Wycofywane identyfikatory OID

Główny zespół odpowiedzialny za Postgres stopniowo wycofuje OID.

Postgres 12 usuwa specjalne zachowanie kolumn OID

Użycie OID jako opcjonalnej kolumny systemowej w tabelach zostało teraz usunięte z Postgres 12. Nie możesz już używać:

  • CREATE TABLE … WITH OIDS Komenda
  • default_with_oids (boolean) ustawienie zgodności

Typ danych OIDpozostaje w Postgres 12. Możesz jawnie utworzyć kolumnę tego typu OID.

Po migracji do Postgres 12 żadna opcjonalnie zdefiniowana kolumna systemowa oid nie będzie już domyślnie niewidoczna. Wykonywanie SELECT *testamentu obejmuje teraz tę kolumnę. Zauważ, że ta dodatkowa kolumna „niespodzianka” może zepsuć naiwnie napisany kod SQL.

Basil Bourque
źródło
5

Aby usunąć wszystkie identyfikatory OID z tabel bazy danych, możesz użyć tego skryptu systemu Linux:

Najpierw zaloguj się jako superużytkownik PostgreSQL:

sudo su postgres

Teraz uruchom ten skrypt, zmieniając YOUR_DATABASE_NAME na nazwę bazy danych:

for tbl in `psql -qAt -c "select schemaname || '.' || tablename from pg_tables WHERE schemaname <> 'pg_catalog' AND schemaname <> 'information_schema';" YOUR_DATABASE_NAME` ; do  psql -c "alter table $tbl SET WITHOUT OIDS" YOUR_DATABASE_NAME ; done

Użyłem tego skryptu, aby usunąć wszystkie moje identyfikatory OID, ponieważ Npgsql 3.0 z tym nie działa i nie jest już ważne dla PostgreSQL.

Rodrigo Boratto
źródło