Системные колонки

5.4. Системные колонки

Каждая таблица имеет несколько системных колонок, которые неявно создаются СУБД. Поэтому, имена этих колонок не могут использоваться таким образом, как имена колонок, определяемых пользователем. (Заметим, что эти ограничения отличаются от тех, где имя является или не является ключевым словом; заключение имени в кавычки не позволит вам избежать этих ограничений.) Вам, действительно, нет необходимости беспокоится об этих колонках, просто знайте что они существуют.

oid

Идентификатор объекта (ID объекта) какой-либо строки. Эта колонка существует только если таблица была создана с использованием WITH OIDS или если была установлена конфигурационная переменная default_with_oids. Тип этой колонки — oid (имя типа такое же как и имя колонки); подробности об этом типе см. в Section 8.16.

tableoid

OID таблицы, содержащей данную строку. Эта колонка специально предназначена для запросов, которые производят выборку из наследуемых иерархий (см. Section 5.8), поскольку без неё, трудно сказать из какой конкретной таблицы получена строка. Чтобы получить имя таблицы, необходимо объединить значение tableoid со значением колонки oid в pg_class.

xmin

Индивидуальный идентификатор (ID транзакции) транзакции вставки для этой версии строки. (Версия строки является особенным состоянием строки; каждое обновление строки создаёт новую версию для той же логической строки.)

cmin

Идентификатор команды (начиная с нуля) внутри транзакции вставки.

xmax

Индивидуальный идентификатор (ID транзакции) транзакции удаления или ноль для восстанавливаемой версии строки. Возможно, что для этой колонки в видимой версии строки будет ненулевое значение. Обычно это говорит, что транзакция удаления пока не завершена или что попытка удаления была отменена (откат транзакции).

cmax

Идентификатор команды внутри транзакции удаления или ноль.

ctid

Физическое расположение версии строки внутри таблицы. Заметим, что значение ctid может быть использовано для очень быстрого определения местоположения версии колонки, значение ctid колонки будет изменяться, если оно обновляется или перемещается при выполнении VACUUM FULL. Таким образом, значение ctid является бесполезным в качестве идентификатора колонки. Для идентифкации логической колонки нужно использовать значение OID, или, даже предпочтительней, серийный номер, определяемый пользователем.

Значения OID являются незначительными 32-битными значениями и назначаются из единого счётчика в пределах кластера баз данных. В больших или долгоживущих базах данных, возможна ситуация, когда счётчик дойдя до максимального значения, начинает отсчёт с нуля. Следовательно, неверно считать значения OID уникальными, пока вы, в данном случае, не предпримите какие-либо шаги, чтобы убедиться в этом. Если вам нужно идентифицировать строки в какой-либо таблице, настоятельно рекомендуется использовать генератор последовательности. Однако, значения OID также могут быть использованы, с учётом нескольких дополнительных предосторожностей:

  • На колонку OID в каждой таблице, где OID будет использоваться для идентификации строк должно быть создано ограничение уникальности. Когда такое ограничение уникальности (или уникальный индекс) существует, СУБД заботится о том, чтобы не генерировать OID, совпадающий с OID уже существующей строки таблицы. (Разумеется, это возможно только если таблица содержит меньше чем 232 (4 миллиарда) строк и на практике размер таблицы гораздо меньше, потому что иначе ухудшается производительность).

  • Значения OID никогда не должны использоваться как уникальные между таблицами; используйте комбинацию tableoid и OID строки, если вам необходим идентификатор в пределах базы данных.

  • Конечно, проблемные таблицы должны быть созданы с использованием WITH OIDS. В PostgreSQL 8.1, по умолчанию используется WITHOUT OIDS.

Идентификаторы транзакций также являются 32-битными. В долгоживущих базах данных, возможно достижение максимального значения счётчика для идентификаторов транзакций и начало отсчёта с нуля. Это не является фатальной проблемой и устраняется соответствующими процедурами обслуживания базы данных; подробности см. в Chapter 23. Однако, неразумно иметь долговременную зависимость от уникальности идентификаторов транзакций (более чем один миллиард транзакций).

Идентификаторы команд также являются 32-битными. Это приводит к жёсткому лимиту в 232 (4 миллиарда) SQL команд внутри одной транзакции. На практике такой лимит не является проблемой, потому что это лимит на количество команд SQL, а не количество обрабатываемых строк. Также как и в PostgreSQL 8.3, только команды, которые действительно изменяют содержимое базы данных будут занимать идентификатор команды.

Back to top

(С) Виктор Вислобоков, 2008-2023