Найти в Дзене

Сгенерированные столбцы в PostgreSQL

Что такое сгенерированный столбец? Ну, сгенерированный столбец - это особый вид столбца, который генерируется из других столбцов. Это то же самое, что и табличные представления, но для столбцов. Существует 2 разных типа генерируемых столбцов. Они могут быть virtual или stored. Виртуальные столбцы всегда вычисляются при чтении и не занимают места в памяти. Сохраненные столбцы вычисляются при записи, а затем занимают место в памяти. Однако стоит отметить, что Postgres поддерживает только сохраненные сгенерированные столбцы. Примеры В этом примере мы создадим таблицу для отслеживания некоторой информации об учениках. Как вы можете видеть здесь, full_name - это сгенерированный столбец, который всегда "first_name last_name". Итак, давайте протестируем это, вставив запись. А теперь давайте убедимся, что у нас есть сгенерированное полное имя: Когда именно это вычисляется? Большинству людей, вероятно, все равно, когда он вычисляет, главное, чтобы он действительно вычислял. Что ж, мне было любо

Что такое сгенерированный столбец?

Ну, сгенерированный столбец - это особый вид столбца, который генерируется из других столбцов. Это то же самое, что и табличные представления, но для столбцов.

Существует 2 разных типа генерируемых столбцов. Они могут быть virtual или stored. Виртуальные столбцы всегда вычисляются при чтении и не занимают места в памяти. Сохраненные столбцы вычисляются при записи, а затем занимают место в памяти. Однако стоит отметить, что Postgres поддерживает только сохраненные сгенерированные столбцы.

Примеры

В этом примере мы создадим таблицу для отслеживания некоторой информации об учениках.

-2

Как вы можете видеть здесь, full_name - это сгенерированный столбец, который всегда "first_name last_name".

Итак, давайте протестируем это, вставив запись.

-3

А теперь давайте убедимся, что у нас есть сгенерированное полное имя:

-4

Когда именно это вычисляется?

Большинству людей, вероятно, все равно, когда он вычисляет, главное, чтобы он действительно вычислял. Что ж, мне было любопытно, поэтому я решил поделиться с вами своими выводами, на случай, если вам интересно.

Итак, очевидно, что он вычисляется, когда мы создаем запись. Но пересчитывает ли он каждый раз, когда изменяется запись? или он достаточно умен, чтобы меняться только тогда, когда меняются столбцы, на которые он опирается? На каком этапе процесса это вычисляется?

Чтобы разобраться в этом, я пошел дальше и добавил в таблицу несколько счетчиков, которые будут отслеживать каждый раз, когда обновляются определенные поля. Я также пошел дальше и добавил before триггер, который будет увеличивать счетчики каждый раз, когда запись обновляется.

-5

Теперь, когда мы настроили счетчики, давайте взглянем на наш пример записи:

-6

Теперь давайте изменим last_name:

-7

Как мы можем видеть, это увеличило last_name и full_name на 1. Как и следовало ожидать.

Теперь давайте изменим first_name:

-8

Как мы можем видеть, это увеличило только полное имя на 1.

Что произойдет, если мы изменим last_name на то же значение, которое у него уже есть? Выполняется ли при этом обновление либо last_name, либо full_name?

-9

Как мы можем видеть, при этом все равно были обновлены last_name и full_name.

Для нашего последнего теста, что произойдет, если мы обновим поле, не связанное с сгенерированным столбцом?

-10

Как мы можем видеть, это обновило счетчик age_counter, но также обновило счетчик full_name_counter . Итак, это подтверждает для нас, что full_name вычисляется каждый раз, когда обновляется запись!

Итак, теперь у нас есть простой сгенерированный столбец, и мы немного больше понимаем, что происходит "под капотом". Но есть ли какие-либо другие ограничения или вещи, о которых мы должны знать?

Некоторые ограничения

Можем ли мы ссылаться на сгенерированный столбец из другого сгенерированного столбца?

-11

После запуска мы увидим следующее:

-12

Увы, мы ограничены здесь и не можем ссылаться на сгенерированный столбец из другого. Что имеет смысл, если подумать, потому что все может стать странным, и вы легко можете столкнуться с какой-нибудь циклической логикой.

Можем ли мы использовать ограничения для сгенерированных столбцов?

За неимением лучшего примера, давайте создадим сгенерированный столбец, вычисляемый на основе возраста учащегося и last_name с ограничением уникальности:

-13

Теперь давайте предположим, что у нас есть наш исходный пример:

-14

И мы хотим добавить в него сестру-близнеца:

-15

Мы получим следующую ошибку:

-16

Краткий итог

Сегодня мы узнали о сгенерированных столбцах. Мы узнали, что это хороший способ вычисления данных "на лету", на уровне базы данных. Мы также узнали, что они вычисляются каждый раз, когда запись вставляется / обновляется, независимо от того, влияют обновленные поля на сгенерированный столбец или нет. Наконец, мы узнали, что по большей части они ведут себя точно так же, как обычные столбцы.