5.3. Генерируемые столбцы#
5.3. Генерируемые столбцы #
Генерируемый столбец - это специальный столбец, который всегда вычисляется на основе других столбцов. Таким образом, он является аналогом представления для таблиц. Существуют два вида генерируемых столбцов: хранимые и виртуальные. Хранимый генерируемый столбец вычисляется при записи (вставке или обновлении) и занимает место в памяти, как обычный столбец. Виртуальный генерируемый столбец не занимает место в памяти и вычисляется при чтении. Таким образом, виртуальный генерируемый столбец похож на представление, а хранимый генерируемый столбец похож на материализованное представление (за исключением того, что он всегда автоматически обновляется). В настоящее время PostgreSQL реализует только хранимые генерируемые столбцы.
Для создания генерируемого столбца используйте предложение GENERATED ALWAYS
AS
в команде CREATE TABLE
, например:
CREATE TABLE people (
...,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED
);
Ключевое слово STORED
должно быть указано для выбора
хранимого типа генерируемого столбца. См. CREATE TABLE для
получения более подробной информации.
Столбец, созданный автоматически, не может быть записан напрямую. В командах INSERT
или UPDATE
нельзя указывать значение для столбца, созданного автоматически, но можно использовать ключевое слово DEFAULT
.
Рассмотрим различия между столбцом со значением по умолчанию и генерируемым столбцом. Значение по умолчанию для столбца вычисляется один раз при первой вставке строки, если другое значение не было указано; генерируемый столбец обновляется каждый раз, когда изменяется строка и не может быть переопределен. Выражение значения по умолчанию для столбца не может ссылаться на другие столбцы таблицы; а генерирующее выражение обычно ссылается на них. Выражение значения по умолчанию для столбца может использовать волатильные функции, например random()
или функции, относящиеся к текущему времени; это не допускается для генерируемых столбцов.
Несколько ограничений применяются к определению генерируемых столбцов и таблиц, включающих генерируемые столбцы:
Генерирующее выражение может использовать только постоянные функции и не может использовать подзапросы или ссылаться на что-либо, кроме текущей строки.
Генерирующее выражение не может ссылаться на другой генерируемый столбец.
Генерирующее выражение не может ссылаться на системный столбец, за исключением столбца
tableoid
.Столбец, созданный автоматически, не может иметь значения по умолчанию или определение идентичности.
Столбец, созданный автоматически, не может быть частью ключа разделения.
Внешние таблицы могут иметь генерируемые столбцы. См. CREATE FOREIGN TABLE для получения подробной информации.
Для наследования и разбиения на секции:
Если родительский столбец является вычисляемым столбцом, его дочерний столбец также должен быть вычисляемым столбцом; однако дочерний столбец может иметь другое генерирующее выражение. Генерирующее выражение, которое фактически применяется при вставке или обновлении строки, связано с таблицей, в которой строка физически находится. (Это отличается от поведения для значений по умолчанию столбца: для них применяется значение по умолчанию, связанное с таблицей, указанной в запросе.)
Если родительский столбец не является генерируемым столбцом, его дочерний столбец также не должен быть генерируемым.
Для унаследованных таблиц, если определение столбца дочерней таблицы задано без предложения
GENERATED
вCREATE TABLE ... INHERITS
, то его предложениеGENERATED
будет автоматически скопировано из родительской таблицы.ALTER TABLE ... INHERIT
будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.Аналогично для секционированных таблиц, если вы пишете определение дочернего столбца без предложения
GENERATED
вCREATE TABLE ... PARTITION OF
, то его предложениеGENERATED
будет автоматически скопировано от родителя.ALTER TABLE ... ATTACH PARTITION
будет требовать, чтобы родительские и дочерние столбцы совпадали по статусу генерирования, но не будет требовать совпадения соответствующих генерирующих выражений.В случае множественного наследования, если один из родительских столбцов является вычисляемым столбцом, то все родительские столбцы должны быть вычисляемыми столбцами. Если у них не одинаковое генерирующее выражение, то необходимое выражение для дочернего столбца должно быть указано явно.
При использовании генерируемых столбцов следует также учитывать следующие моменты:
Права доступа к генерируемым столбцам отдельны от прав доступа к базовым столбцам. Таким образом, можно настроить определенную роль так, чтобы она могла прочитать генерируемый столбец, но не базовые столбцы.
Генерируемые столбцы, по определению, обновляются после выполнения триггеров
BEFORE
. Поэтому изменения, внесенные в базовые столбцы в триггереBEFORE
, будут отражены в генерируемых столбцах. Но получить доступ к генерируемым столбцам в триггерахBEFORE
нельзя.Генерируемые столбцы пропускаются для логической репликации и не могут быть указаны в списке столбцов
CREATE PUBLICATION
.