Типы идентификаторов объектов

Идентификаторы объектов (OID) используются внутри QHB в качестве первичных ключей для различных системных таблиц. Идентификатор объекта представляется типом oid. Также для oid определено несколько типов-псевдонимов с именами вида regсущность. Обзор этих псевдонимов представлен в Таблице 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');

Хотя второй запрос сам по себе не так уж плох, он все равно чересчур упрощен. Если в разных схемах есть несколько таблиц с именем mytable, то для выбора правильного OID потребуется гораздо более сложный подзапрос. Преобразователь вводимого значения типа regclass находит таблицу в соответствии с настройкой пути к схеме, поэтому автоматически выполняет «правильные действия». Точно так же приведение OID таблицы к типу regclass удобно для символического отображения числового OID.

Таблица 26. Типы идентификаторов объектов

ИмяСсылкиОписаниеПример значения
oidЛюбыечисловой идентификатор объекта564182
regclasspg_classимя отношенияpg_type
regcollationpg_collationимя правила сортировки"POSIX"
regconfigpg_ts_configконфигурация текстового поискаenglish
regdictionarypg_ts_dictсловарь текстового поискаsimple
regnamespacepg_namespaceимя пространства именpg_catalog
regoperpg_operatorимя оператора+
regoperatorpg_operatorоператор с типами аргументов*(integer,integer) или -(NONE,integer)
regprocpg_procимя функцииsum
regprocedurepg_procфункция с типами аргументовsum(int4)
regrolepg_authidимя ролиsmithee
regtypepg_typeимя типа данныхinteger

Все типы-псевдонимы OID для объектов, сгруппированных в пространстве имен, принимают имена, дополненные именем схемы, и будут выводить имена со схемой, если этот объект нельзя найти в текущем пути поиска без имени схемы. Например, myschema.mytable является приемлемым входным значением для regclass (если такая таблица существует). Это значение может выводиться как myschema.mytable или просто mytable, в зависимости от текущего пути поиска. Типы-псевдонимы regproc и regoper принимают только уникальные вводимые имена (не перегруженные), поэтому их использование ограничено; в большинстве случаев больше подходят regprocedure или regoperator. Для regoperator при определении унарных операторов вместо неиспользуемого операнда записывается слово NONE.

Функции ввода для данных типов допускают пробелы между синтаксическими единицами и приводят буквы верхнего регистра к нижнему, за исключением строки в кавычках; это сделано для того, чтобы правила синтаксиса были похожа на принятые для записи имен объектов в SQL. И наоборот, функции вывода будут при необходимости использовать кавычки, чтобы выводимая строка была допустимым идентификатором SQL. Например,OID функции с именем FooF в верхнем регистре), принимающей два целочисленных аргумента, можно ввести как ' "Foo" ( int, integer ) '::regprocedure. Вывод будет выглядеть как "Foo"(integer,integer). Как имя функции, так и имена типов аргументов также могут быть дополнены схемой.

Многие встроенные функции QHB принимают 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() и подобные ей. См. таблицу Функции для получения информации из системных каталогов.

Другой практический пример использования 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), QHB понимает, что это выражение зависит от последовательности my_seq; система не позволит удалить последовательность, не удалив предварительно выражение по умолчанию. Альтернативная запись nextval('my_seq'::text) не создает зависимость. (Тип regrole является единственным исключением для этого свойства. Константы этого типа в таких выражениях не допускаются.)

Другим типом идентификаторов, используемым системой, является xid, или идентификатор транзакции (сокращенно xact). Это тип данных системных столбцов xmin и xmax. Идентификаторы транзакции являются 32-битными величинами. В некоторых контекстах используется 64-битный вариант xid8. В отличие от значений xid, значения xid8 увеличиваются строго монотонно и не могут быть повторно использованы на протяжении всего существования кластера баз данных.

Третий тип идентификатора, используемый системой, — cid, или идентификатор команды. Это тип данных системных столбцов cmin и cmax. Идентификаторы команд также являются 32-битными величинами.

Последний тип идентификатора, используемый системой, — это tid, или идентификатор кортежа (идентификатор строки). Это тип данных системного столбца ctid. Идентификатор кортежа — это пара (номер блока, индекс кортежа в блоке), которая определяет физическое расположение строки в таблице.

(Более подробно системные столбцы рассматриваются в разделе Системные столбцы).