База знаний по Open Source
Авторизация
Поиск по базе знаний

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

oid

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

tableoid

OID таблицы, содержащей данную строку. Эта колонка специально предназначена для запросов, которые производят выборку из наследуемых иерархий, поскольку без неё, трудно сказать из какой конкретной таблицы получена строка. Чтобы получить имя таблицы, необходимо объединить значение 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.

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

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