Типы идентификаторов объектов
Идентификаторы объектов (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 |
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) |
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)
. Как имя функции, так и имена типов
аргументов также могут быть дополнены схемой.
Многие встроенные функции 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. Идентификатор кортежа — это пара (номер блока, индекс кортежа в блоке), которая определяет физическое расположение строки в таблице.
(Более подробно системные столбцы рассматриваются в разделе Системные столбцы).