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

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

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

Идентификаторы объектов (OID) используются внутри Tantor SE в качестве первичных ключей для различных системных таблиц. Тип oid представляет собой идентификатор объекта. Также существует несколько псевдонимов для типа oid, каждый из которых называется regsomething. Таблица 8.26 показывает обзор.

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

Тип oid сам по себе имеет немного операций, кроме сравнения. Однако его можно привести к типу integer и затем использовать стандартные операторы для работы с целыми числами. (Остерегайтесь возможной путаницы между знаковыми и беззнаковыми значениями при этом).

Типы псевдонимов 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 обрабатывает поиск таблицы в соответствии с настройкой пути схемы, и поэтому он автоматически делает правильное. Аналогично, приведение OID таблицы к типу regclass удобно для символического отображения числового OID.

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

ИмяСсылкиОписаниеПример значения
oidanyчисловой идентификатор объекта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 функции с именем Foo (с заглавной буквы F), принимающей два целочисленных аргумента, можно ввести как ' "Foo" ( int, integer ) '::regprocedure. Вывод будет выглядеть как "Foo"(integer,integer). Имя функции и имена типов аргументов также можно указать с указанием схемы.

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

nextval('foo')              работает с последовательностью foo
nextval('FOO')              так же, как выше
nextval('"Foo"')            работает с последовательностью Foo
nextval('myschema.foo')     operates on myschema.foo
nextval('"myschema".foo')   так же, как выше
nextval('foo')              ищет пути поиска для foo

Примечание

Когда вы указываете аргумент такой функции в виде обычной литеральной строки, он становится константой типа regclass (или соответствующего типа). Поскольку это на самом деле просто OID, он будет отслеживать исходно идентифицированный объект, несмотря на последующее переименование, переназначение схемы и т. д. Это поведение преждевременного связывания обычно желательно для ссылок на объекты в значениях по умолчанию столбцов и представлениях. Но иногда вам может понадобиться позднее связывание, когда ссылка на объект разрешается во время выполнения. Чтобы получить поведение позднего связывания, принудительно сохраните константу как константу типа text, а не regclass:

nextval('foo'::text)      foo ищется во время выполнения

Функция to_regclass() и ее аналоги также могут использоваться для выполнения поиска во время выполнения. См. Таблица 9.71.

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

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

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

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

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