SQL, OIDs Postgres, что они и чем они полезны?

161

Я смотрю на создание таблиц в PostgreSQL и наткнулся на это:

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

Я прочитал документацию, предоставленную postgres, и я знаю концепцию идентификатора объекта из ООП, но все же я не понимаю,

  • почему такой идентификатор будет полезен в базе данных?
  • сделать запросы короче?
  • когда его следует использовать?
fabrizioM
источник
На данный момент я не могу найти никаких ссылок, чтобы цитировать, но к вашему сведению, я слышал, что использование Microsoft Access в качестве внешнего интерфейса для Postgres требует наличия oldсистемного столбца .
Василий Бурк

Ответы:

165

OID в основном предоставляют встроенный глобально уникальный идентификатор для каждой строки, содержащейся в системном столбце (в отличие от столбца пользовательского пространства). Это удобно для таблиц, в которых у вас нет первичного ключа, есть повторяющиеся строки и т. Д. Например, если у вас есть таблица с двумя одинаковыми строками и вы хотите удалить самую старую из двух, вы можете сделать это, используя колонка oid.

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

В PostgreSQL 8.1 default_with_oids по умолчанию отключено; в предыдущих версиях PostgreSQL он был включен по умолчанию.

Использование OID в пользовательских таблицах считается устаревшим, поэтому большинство установок должны оставлять эту переменную отключенной. Приложения, которым требуются OID для конкретной таблицы, должны указывать WITH OIDS при создании таблицы. Эта переменная может быть включена для совместимости со старыми приложениями, которые не следуют этому поведению.

Фрэнк Фармер
источник
33
oids не гарантируется быть уникальным. Из документов: «В большой или долгоживущей базе данных счетчик может обернуться. Следовательно, считается плохой практикой предполагать, что идентификаторы OID уникальны, если только вы не предпримете шаги, чтобы убедиться, что это так».
радиоспил
8
Обтекание также подразумевает, что вы не обязательно можете удалить более старую из двух строк, основываясь только на их OID, так как та, которая имеет более низкий OID, могла быть обтеканием.
Карл Дж.
OIDs не являются глобально уникальными, согласно комментариям выше, и не были в 2011 году, когда был написан этот ответ. Кроме того, OID необходимы для системных объектов, поэтому использование всех OID на счетчиках строк не помогает базе данных назначать OID для новых таблиц (для таблицы, а не для ее строк). Кроме того, подумайте, действительно ли одного 4-байтового счетчика целых чисел будет достаточно для каждой таблицы в вашей базе данных.
FuzzyChef
Стоит отметить, что в большинстве реализаций phpPgAdmin при создании таблицы этот параметр отключен по умолчанию, что означает, что этот параметр является устаревшим.
vdegenne
3
если вы не знаете, для чего используются OID, вы, вероятно, не хотите их использовать.
vdegenne
16

OID все еще используются для Postgres с большими объектами (хотя некоторые люди утверждают, что большие объекты в общем случае бесполезны). Они также широко используются системными таблицами . Они используются, например, TOAST, который хранит BYTEA размером более 8 КБ (и т. Д.) В отдельной области хранения (прозрачно), которая используется по умолчанию во всех таблицах . Их прямое использование, связанное с «обычными» пользовательскими таблицами, в основном не рекомендуется .

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

Очевидно, последовательность OID «оборачивается», если она превышает 4B 6 . Так что по сути это глобальный счетчик, который может обернуться Если это произойдет, может произойти некоторое замедление, когда он будет использован и "найден" для поиска уникальных значений и т. Д.

Смотрите также https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F.

rogerdpack
источник
9

OIDs постепенно сокращаются

Основная команда, ответственная за 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.

Родриго Борато
источник