PostgreSQL 12 Yenilikleri: Generated Columns

Merhaba,

Bu yılın sonuna doğru PostgreSQL 12'nin yayınlanması bekleniyor. Yeni özelliklerin eklenmesi yanı sıra, mevcut özellikler üzerinde değişiklikler de yapıldı. Yeni gelen özelliklerden biri "Generated Columns" yapısı. PostgreSQL 12 ile gelen yeniliklerden bahsettiğim sunumuma buradan ulaşabilirsiniz.

Generated Columns, tabloda yer alan diğer sütunların kullanılmasıyla meydana gelen sütunlardır. Bunun iki çeşidi vardır: Stored ve Virtual. Stored olan sütunun yeni değerini hesaplar ve tabloya yeni veriyi yazar. Virtual is bir view gibi davranır. ilgili sütun her kullanıldığında değeri yeniden hesaplanır. Postgres bunlardan Stored olanını kullanır. 
Dikkat edilmesi gereken bir kaç konu var:
  • INSERT/UPDATE komutları Generated Column için kullanılamaz.
  • Generated Column Partition Key olamaz.
  • Generated Column başka bir Generated Column kullanılarak oluşturulamaz.
Standart SQL ve PostgreSQL'de olduğu gibi sıradan bir tablo oluşturalım. 

test=# CREATE TABLE gc_test (c1 int, c2 int);
CREATE TABLE

test=# INSERT INTO gc_test SELECT GENERATE_SERIES(1,5), GENERATE_SERIES(1,3);
INSERT 0 5

test=# SELECT * FROM gc_test;
 c1 | c2
----+----
  1 |  1
  2 |  2
  3 |  3
  4 | 
  5 | 
(5 rows)

Bu tabloyu Generated Column ile oluşturalım.

test=# DROP TABLE gc_test;
DROP TABLE


test=# CREATE TABLE gc_test (c1 int, c2 int, c3 int GENERATED ALWAYS AS (c1+c2) STORED);
CREATE TABLE


test=# INSERT INTO gc_test SELECT GENERATE_SERIES(1,5), GENERATE_SERIES(1,3);
INSERT 0 5


test=# SELECT * FROM gc_test ;
 c1 | c2 | c3
----+----+----
  1 |  1 |  2
  2 |  2 |  4
  3 |  3 |  6
  4 |    |  
  5 |    |  
(5 rows)

c3 sütunu c1 ve c2 sütunlarının toplamından oluşuyor ve her satır INSERT edildiğinde aynı zamanda veritabanına bu değer yazılıyor.
Bir Generated Column'a sahip bu tablonun yapısına bakalım. Default değeri c1+c2 olarak görünüyor. 
 
test=# \d gc_test
                             Table "public.gc_test"
 Column |  Type   | Collation | Nullable |               Default              
--------+---------+-----------+----------+--------------------------------------
 c1     | integer |           |          |
 c2     | integer |           |          |
 c3     | integer |           |          | generated always as (c1 + c2) stored

Bir Generated Column'un DEFAULT değerini farklı bir DEFAULT değer ile değiştiremezsiniz.

test=# ALTER TABLE gc_test ALTER COLUMN c3 SET DEFAULT 5;
psql: ERROR:  column "c3" of relation "gc_test" is a generated column

Generated Column'un mevcut DEFAULT değeri bulunmakta. Bu özel sütunlar farklı bir değer ile UPDATE edilemez. 

test=# UPDATE gc_test SET c3=1 where c1=1;
psql: ERROR:  column "c3" can only be updated to DEFAULT
DETAIL:  Column "c3" is a generated column.

Generated Column'u kendisine atanmış DEFAULT değeri ile güncelleyebilirsiniz.

test=# UPDATE gc_test SET c3=DEFAULT where c1=1;
UPDATE 1

Bir tabloya Generated Column eklendiğinde o sütunun yeni değerinin hesaplanması için baştan sona güncellenir. Bu aynı zamanda bir tabloya DEFAULT değeri olan bir sütun eklemek ile aynı işlemi yapar. Dikkat etmek gerekir.

test=# ALTER TABLE gc_test ADD COLUMN c4 text GENERATED ALWAYS AS (c1::text || c2::text) STORED;
ALTER TABLE


test=# \d gc_test
                                   Table "public.gc_test"
 Column |  Type   | Collation | Nullable |                      Default                    
--------+---------+-----------+----------+---------------------------------------------------
 c1     | integer |           |          |
 c2     | integer |           |          |
 c3     | integer |           |          | generated always as (c1 + c2) stored
 c4     | text    |           |          | generated always as (c1::text || c2::text) stored

test=# SELECT * FROM gc_test ;
 c1 | c2 | c3 | c4
----+----+----+----
  2 |  2 |  4 | 22
  3 |  3 |  6 | 33
  4 |    |    |
  5 |    |    |
  1 |  1 |  2 | 11
(5 rows)

Sevgiler

Comments

Popular posts from this blog

PostgreSQL High Availability - Patroni 2

PostgreSQL Foreign Data Wrappers

PostgreSQL High Availability - Patroni 1