8.19. Идентификаторы объектов
Идентификатор объекта (Object Identifier, OID) используется внутри Postgres Pro в качестве первичного ключа различных системных таблиц. Идентификатор объекта представляется в типе oid
. Также существуют различные типы-псевдонимы для oid
, с именами reg
. Обзор этих типов приведён в Таблице 8.26.сущность
В настоящее время тип oid
реализован как четырёхбайтное целое число без знака. Таким образом, значение этого типа может быть недостаточно большим для обеспечения уникальности в базе данных или даже в отдельных больших таблицах.
Для самого типа oid
помимо сравнения определены всего несколько операторов. Однако его можно привести к целому и затем задействовать в обычных целочисленных вычислениях. (При этом следует опасаться путаницы со знаковыми/беззнаковыми значениями.)
Типы-псевдонимы OID сами по себе не вводят новых операций и отличаются только специализированными функциями ввода/вывода. Эти функции могут принимать и выводить не просто числовые значения, как тип oid
, а символические имена системных объектов. Эти типы позволяют упростить поиск объектов по значениям OID. Например, чтобы выбрать из pg_attribute
строки, относящиеся к таблице mytable
, можно написать:
SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;
вместо:
SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');
Хотя второй вариант выглядит не таким уж плохим, но это лишь очень простой запрос. Если же потребуется выбрать правильный OID, когда таблица mytable
есть в нескольких схемах, вложенный подзапрос будет гораздо сложнее. Преобразователь вводимого значения типа regclass
находит таблицу согласно заданному пути поиска схем, так что он делает «всё правильно» автоматически. Аналогично, приведя идентификатор таблицы к типу regclass
, можно получить символическое представление числового кода.
Таблица 8.26. Идентификаторы объектов
Имя | Ссылки | Описание | Пример значения |
---|---|---|---|
oid | any | числовой идентификатор объекта | 564182 |
regclass | pg_class | имя отношения | pg_type |
regcollation | pg_collation | имя правила сортировки | "POSIX" |
regconfig | pg_ts_config | конфигурация текстового поиска | english |
regdictionary | pg_ts_dict | словарь текстового поиска | simple |
regnamespace | pg_namespace | пространство имён | pg_catalog |
regoper | pg_operator | имя оператора | + |
regoperator | pg_operator | оператор с типами аргументов | *(integer,integer) или -(NONE,integer) |
regproc | pg_proc | имя функции | sum |
regprocedure | pg_proc | функция с типами аргументов | sum(int4) |
regprofile | pg_profile | имя профиля | default |
regrole | pg_authid | имя роли | smithee |
regtype | pg_type | имя типа данных | integer |
Все типы псевдонимов OID для объектов, сгруппированных в пространство имён, принимают имена, дополненные именем схемы, и выводят имена со схемой, если данный объект нельзя будет найти в текущем пути поиска без имени схемы. Например, myschema.mytable
является приемлемым входным значением для regclass
(если существует такая таблица). Это значение может выводиться как myschema.mytable
или просто mytable
, в зависимости от текущего пути поиска. Типы regproc
и regoper
принимают только уникальные вводимые имена (не перегруженные), что ограничивает их применимость; в большинстве случаев лучше использовать regprocedure
или regoperator
. Для типа regoperator
в записи унарного оператора неиспользуемый операнд заменяется словом NONE
.
Функции ввода для данных типов допускают пробелы между компонентами и приводят буквы верхнего регистра к нижнему, за исключением строки в двойных кавычках; это сделано для того, чтобы правила записи были похожи на принятые для записи имён объектов в SQL. И наоборот, функции вывода будут добавлять двойные кавычки, если это необходимо, чтобы выводимая строка была допустимым идентификатором SQL. Например, OID функции с именем Foo
(с F
в верхнем регистре), принимающей два целочисленных аргумента, можно ввести как ' "Foo" ( int, integer ) '::regprocedure
. Результат будет выглядеть как "Foo"(integer,integer)
. И имя функции, и имена типов аргументов также могут быть дополнены схемой.
Многие встроенные функции PostgreSQL принимают OID таблицы или другого типа объекта БД и для удобства объявляются как принимающие regclass
(или соответствующий тип-псевдоним OID). Это означает, что вам не нужно искать OID объекта вручную, а можно просто ввести его имя в виде строки. Например, функция nextval (regclass)
принимает OID отношения последовательности, поэтому её можно вызвать так:
nextval('foo') обращается к последовательностиfoo
nextval('FOO') то же самое nextval('"Foo"') обращается к последовательностиFoo
nextval('myschema.foo') обращается кmyschema.foo
nextval('"myschema".foo') то же самое nextval('foo') ищетfoo
в пути поиска
Примечание
Когда аргумент такой функции записывается как текстовая строка в чистом виде, она становится константой типа regclass
. Так как фактически это будет просто значение OID, оно будет привязано к изначально идентифицированной последовательности, несмотря на то, что она может быть переименована, перенесена в другую схему и т. д. Такое «раннее связывание» обычно желательно для ссылок на последовательности в значениях столбцов по умолчанию и представлениях. Но иногда возникает необходимость в «позднем связывании», когда ссылки на последовательности распознаются в процессе выполнения. Чтобы получить такое поведение, нужно принудительно изменить тип константы с regclass
на text
:
nextval('foo'::text) foo
распознаётся во время выполнения
Для поиска во время выполнения также может использоваться функция to_regclass()
и подобные. См. Таблицу 9.75.
Другой практический пример использования regclass
— поиск OID таблицы, отображённой в представлениях information_schema
, которые не предоставляют такие OID напрямую. Например, можно вызвать функцию pg_relation_size()
, для которой требуется OID таблицы. С учётом указанных выше правил, далее представлен корректный способ вызова данной функции
SELECT table_schema, table_name, pg_relation_size((quote_ident(table_schema) || '.' || quote_ident(table_name))::regclass) FROM information_schema.tables WHERE ...
. Функция quote_ident()
заключит идентификатор в двойные кавычки, когда это необходимо. Более простым способом кажется
SELECT pg_relation_size(table_name) FROM information_schema.tables WHERE ...
но использовать его не рекомендуется, потому что он не сработает для таблиц, которые не входят в заданный путь поиска или имена которых нужно заключать в кавычки.
Дополнительным свойством большинства типов псевдонимов OID является образование зависимостей. Когда в сохранённом выражении фигурирует константа одного из этих типов (например, в представлении или в значении столбца по умолчанию), это создаёт зависимость от целевого объекта. Например, если значение по умолчанию определяется выражением nextval('my_seq'::regclass)
, Postgres Pro понимает, что это выражение зависит от последовательности my_seq
, и не позволит удалить последовательность раньше, чем будет удалено это выражение. Альтернативная запись nextval('my_seq'::text)
не создаёт зависимость. (Исключениями являются типы regprofile
и regrole
. Константы этих типов в таких выражениях не допускаются.)
Есть ещё один тип системных идентификаторов, xid
, представляющий идентификатор транзакции (сокращённо xact). Этот тип имеют системные столбцы xmin
и xmax
. Идентификаторы транзакций определяются 32-битными числами. В некоторых контекстах используется 64-битный вариант xid8
. В отличие от xid
, значения xid8
увеличиваются строго монотонно и никогда не повторяются на протяжении всего существования кластера баз данных.
Третий тип идентификаторов, используемых в системе, — cid
, идентификатор команды (command identifier). Этот тип данных имеют системные столбцы cmin
и cmax
. Идентификаторы команд — это тоже 32-битные числа.
И наконец, последний тип системных идентификаторов — tid
, идентификатор строки/кортежа (tuple identifier). Этот тип данных имеет системный столбец ctid
. Идентификатор кортежа представляет собой пару (из номера блока и индекса кортежа в блоке), идентифицирующую физическое расположение строки в таблице.
(Подробнее о системных столбцах рассказывается в Разделе 5.5.)