SQL, Postgres OID, Apa itu dan mengapa mereka berguna?

161

Saya melihat beberapa pembuatan tabel PostgreSQL dan saya menemukan ini:

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

Saya membaca dokumentasi yang disediakan oleh postgres dan saya tahu konsep pengenal objek dari OOP tetapi saya masih tidak mengerti,

  • mengapa pengidentifikasi seperti itu akan berguna dalam database?
  • untuk membuat pertanyaan lebih pendek?
  • kapan itu harus digunakan?
fabrizioM
sumber
Saya tidak dapat menemukan referensi untuk dikutip saat ini, tetapi FYI saya telah mendengar bahwa menggunakan Microsoft Access sebagai front-end ke Postgres memerlukan keberadaan oldkolom sistem .
Basil Bourque

Jawaban:

165

OID pada dasarnya memberi Anda id internal yang unik secara global untuk setiap baris, yang terkandung dalam kolom sistem (bukan kolom ruang pengguna). Itu berguna untuk tabel di mana Anda tidak memiliki kunci utama, memiliki baris duplikat, dll. Misalnya, jika Anda memiliki tabel dengan dua baris yang identik, dan Anda ingin menghapus yang tertua dari keduanya, Anda bisa melakukannya dengan menggunakan kolom oid.

Dalam pengalaman saya, fitur ini umumnya tidak digunakan di sebagian besar aplikasi yang didukung postgres (mungkin sebagian karena mereka non-standar), dan penggunaannya pada dasarnya sudah usang :

Di PostgreSQL 8.1 default_with_oids dinonaktifkan secara default; dalam versi PostgreSQL sebelumnya, ini diaktifkan secara default.

Penggunaan OID dalam tabel pengguna dianggap sudah usang, sehingga sebagian besar instalasi harus membuat variabel ini dinonaktifkan. Aplikasi yang membutuhkan OID untuk tabel tertentu harus menentukan DENGAN OIDS saat membuat tabel. Variabel ini dapat diaktifkan untuk kompatibilitas dengan aplikasi lama yang tidak mengikuti perilaku ini.

Frank Farmer
sumber
33
OID tidak dijamin unik. Dari dokumen: "Dalam basis data yang besar atau berumur panjang, konter dapat digunakan untuk membungkusnya. Oleh karena itu, praktik yang buruk untuk mengasumsikan bahwa OID adalah unik, kecuali jika Anda mengambil langkah-langkah untuk memastikan bahwa inilah masalahnya."
radiospiel
8
Pembungkusan sekitar juga menyiratkan bahwa Anda tidak dapat serta merta menghapus yang lebih tua dari dua baris hanya berdasarkan pada OID mereka, karena yang dengan OID yang lebih rendah mungkin merupakan pembungkus.
Carl G
OID tidak unik secara global, per komentar di atas, juga tidak pada 2011 ketika jawaban ini ditulis. Juga, OID diperlukan untuk objek sistem, jadi menggunakan semua OID pada penghitung baris tidak membantu database dengan menetapkan OID ke tabel baru (untuk tabel, bukan barisnya). Juga, pertimbangkan apakah penghitung integer 4-byte menghanguskan benar-benar akan cukup untuk setiap tabel dalam database Anda.
FuzzyChef
Perlu disebutkan, dalam sebagian besar implementasi phpPgAdmin saat membuat tabel, opsi ini dicentang nonaktifkan sebagai default, artinya dalam kenyataannya fakta bahwa opsi ini sudah usang.
vdegenne
3
jika Anda tidak tahu untuk apa OID digunakan maka Anda mungkin tidak ingin menggunakannya.
vdegenne
16

OID masih digunakan untuk Postgres dengan objek besar (meskipun beberapa orang berpendapat objek besar umumnya tidak berguna). Mereka juga digunakan secara luas oleh tabel sistem . Mereka digunakan misalnya oleh TOAST yang menyimpan lebih besar dari 8KB BYTEA (dll.) Ke area penyimpanan terpisah (transparan) yang digunakan secara default oleh semua tabel . Penggunaan langsung mereka yang terkait dengan tabel pengguna "normal" pada dasarnya sudah usang .

Jenis oid saat ini diimplementasikan sebagai integer empat byte yang tidak ditandatangani. Oleh karena itu, tidak cukup besar untuk menyediakan keunikan di seluruh basis data di basis data besar, atau bahkan dalam tabel individual besar. Jadi, menggunakan kolom OID tabel yang dibuat pengguna sebagai kunci utama tidak disarankan. OID paling baik digunakan hanya untuk referensi ke tabel sistem.

Rupanya urutan OID "tidak" membungkus jika melebihi 4B 6 . Jadi pada dasarnya ini adalah penghitung global yang dapat membungkus. Jika itu membungkus, beberapa pelambatan mungkin mulai terjadi ketika digunakan dan "mencari" nilai-nilai unik, dll.

Lihat juga https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

rogerdpack
sumber
9

OID sedang dihapus

Tim inti yang bertanggung jawab untuk Postgres secara bertahap menghapus OID.

Postgres 12 menghapus perilaku khusus kolom OID

Penggunaan OID sebagai kolom sistem opsional pada tabel Anda sekarang dihapus dari Postgres 12. Anda tidak dapat lagi menggunakan:

  • CREATE TABLE … WITH OIDS perintah
  • default_with_oids (boolean) pengaturan kompatibilitas

Tipe data OIDtetap di Postgres 12. Anda dapat secara eksplisit membuat kolom dari tipe tersebut OID.

Setelah bermigrasi ke Postgres 12 , kolom sistem apa pun yang ditentukan secara opsional oidtidak akan lagi terlihat oleh default. Pertunjukan SELECT *sekarang akan mencakup kolom ini. Perhatikan bahwa kolom "kejutan" ekstra ini dapat memecah kode SQL yang ditulis dengan naif.

Basil Bourque
sumber
5

Untuk menghapus semua OID dari tabel basis data Anda, Anda dapat menggunakan skrip Linux ini:

Pertama, masuk sebagai superuser PostgreSQL:

sudo su postgres

Sekarang jalankan skrip ini, ubah YOUR_DATABASE_NAME dengan nama basis data Anda:

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

Saya menggunakan skrip ini untuk menghapus semua OID saya, karena Npgsql 3.0 tidak berfungsi dengan ini, dan tidak penting lagi untuk PostgreSQL.

Rodrigo Boratto
sumber