SQL, Postgres OID, що вони є і для чого вони корисні?


161

Я переглядаю створення таблиці PostgreSQL і натрапив на це:

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

Я читаю документацію, подану postgres, і знаю поняття ідентифікатора об'єктів від OOP, але все ще не розумію,

  • чому такий ідентифікатор був би корисним у базі даних?
  • щоб скоротити запити?
  • коли його слід використовувати?

На даний момент я не можу знайти жодних посилань, які цитують, але FYI я чув, що для використання Microsoft Access як переднього до Postgres потрібна наявність oldстовпця системи .
Василь Бурк

Відповіді:


165

По суті, OID надають вбудований глобальний унікальний ідентифікатор для кожного рядка, що міститься в системному стовпці (на відміну від стовпця з простором користувача). Це зручно для таблиць, де у вас немає первинного ключа, є повторювані рядки тощо. Наприклад, якщо у вас є таблиця з двома однаковими рядками, і ви хочете видалити найстаріший з двох, ви можете зробити це за допомогою oid стовпчик.

На мій досвід, ця функція, як правило, не використовується в більшості програм, захищених постгресами (можливо, частково через те, що вони нестандартні), і їх використання по суті застаріло :

У PostgreSQL 8.1 за замовчуванням вимкнено default_with_oids; у попередніх версіях PostgreSQL він був за замовчуванням.

Використання OID в таблицях користувачів вважається застарілим, тому більшість установок повинні залишати цю змінну вимкненою. Програми, які потребують OID для певної таблиці, повинні вказувати З OIDS під час створення таблиці. Цю змінну можна включити для сумісності зі старими програмами, які не дотримуються такої поведінки.


33
oids не гарантовано є унікальним. З документів: "У великій або довговічній базі даних лічильник може обернутися. Отже, погана практика вважати, що OID унікальні, якщо ви не вживаєте заходів для того, щоб це було так".
radiospiel

8
Обгортання також означає, що ви не повинні видаляти старіші з двох рядів на основі лише їх OID, оскільки той, що має нижчий OID, може бути завершенням.
Карл Г

Ідентифікатори OID не є унікальними в усьому світі за коментарями вище, а також не були в 2011 році, коли ця відповідь була написана. Крім того, OID необхідні для системних об'єктів, тому використання всіх OID на лічильниках рядків не допомагає базі даних призначати OID для нових таблиць (для таблиці, а не для її рядків). Крім того, врахуйте, чи дійсно буде окремий 4-байтовий цілочисельний лічильник, достатньо для кожної таблиці вашої бази даних.
FuzzyChef

Варто зазначити, що в більшості реалізації phpPgAdmin при створенні таблиці параметр перевіряється вимкнутим як за замовчуванням, що означає, що ця опція застаріла.
vdegenne

3
якщо ви не знаєте, для чого використовуються OID, ви, ймовірно, не хочете їх використовувати.
vdegenne

16

OID досі використовуються для Postgres з великими об'єктами (хоча деякі люди стверджують, що великі об'єкти взагалі не корисні). Вони також широко використовуються системними таблицями . Вони використовуються, наприклад, TOAST, який зберігає більше 8 КБ BYTEA (і т.д.) в окрему зону зберігання (прозоро), яка використовується за замовчуванням у всіх таблицях . Їх безпосереднє використання, пов'язане з "нормальними" таблицями користувачів, в основному застаріле .

Тип oid в даний час реалізований у вигляді безпідписаного чотирибайтового цілого числа. Отже, вона недостатньо велика, щоб забезпечити унікальність для всіх баз даних у великих базах даних або навіть у великих окремих таблицях. Отже, використання створеного користувачем таблиці стовпців OID в якості основного ключа не рекомендується. OID найкраще використовувати лише для посилань на системні таблиці.

Мабуть, послідовність OID "робить" обгортання, якщо вона перевищує 4B 6 . Тож по суті це глобальний лічильник, який може обернутись. Якщо вона завершиться, може початися деяке уповільнення при її використанні та "пошуку" унікальних значень тощо.

Дивіться також https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F


9

OID припиняються

Основна команда, відповідальна за Postgres, поступово припиняє використання OID.

Postgres 12 видаляє особливу поведінку стовпців OID

Використання OID як необов'язкового системного стовпця у ваших таблицях тепер видалено з Postgres 12. Ви більше не можете використовувати:

  • CREATE TABLE … WITH OIDS командування
  • default_with_oids (boolean) налаштування сумісності

Тип даних OIDзалишається в Postgres 12. Ви можете явно створити стовпець цього типу OID.

Після переходу на Postgres 12 будь-який необов'язково визначений системний стовпець oid більше не буде невидимим за замовчуванням. Виконання SELECT *заповіту тепер буде включати цей стовпець. Зверніть увагу, що цей додатковий стовпець "сюрприз" може порушити наївний SQL код.


5

Щоб видалити всі OID з таблиць вашої бази даних, ви можете використовувати цей скрипт Linux:

По-перше, увійдіть як суперресурс PostgreSQL:

sudo su postgres

Тепер запустіть цей сценарій, змінивши YOUR_DATABASE_NAME з вашою назвою бази даних:

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

Я використовував цей скрипт, щоб видалити всі мої OID, оскільки Npgsql 3.0 не працює з цим, і це вже не важливо для PostgreSQL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.