PostgreSQL: Oluşturulan Sütunlar


16

PostgreSQL oluşturulan sütunları destekliyor mu ? Sanal sütunlar olarak da bilin . Ben am değil bahsediyor IDENTITYsütunlar .

Bu olağanüstü özellik hakkında herhangi bir bilgi bulamıyorum ancak SQL Server'da ve MariaDB & MySQL'in en son sürümlerinde mevcut olduğunu biliyorum.

Özellik SQL: 2003 standardında belirtilmiştir ve 2006 civarında PostgreSQL forumlarında bazı tartışmalar olmuştur, ancak konu hakkında önemli bir şey bulamıyorum.

SO hakkında bazı tartışmalar var, ama şimdi oldukça eski, bu yüzden güncelliğini yitirmiş olabilir.


2
2012'de SO ile ilgili bu yanıt yardımcı olabilir: stackoverflow.com/questions/11165450/… Hala geçerli.
Erwin Brandstetter

@ErwinBrandstetter Üzgünüm Bu yorumu özledim. Yararlı bir numara. Teşekkürler.
Manngo

Yanıtlar:


17

Bunun istediğinizden emin değilim, ancak özellik gösterimi row.full_nameve işlev gösterimifull_name(row) postgresql'de eşdeğerdir.

Yani bir masa tuttun

CREATE TABLE people (
  first_name text,
  last_name text
);

ve bir fonksiyon:

CREATE FUNCTION full_name(people) RETURNS text AS $$
  SELECT $1.first_name || ' ' || $1.last_name;
$$ LANGUAGE SQL;

ve şöyle deyin:

select full_name from people

İhtiyacın olan bu mu?

İşleri hızlandırmak için bir ifade dizini oluşturabilirsiniz:

CREATE INDEX people_full_name_idx ON people
USING GIN (to_tsvector('english', full_name(people)));

Veya her şeyi materyalize bir görünümde saklayın.

Buradan alınan örnek: http://bernardoamc.github.io/sql/2015/05/11/postgres-virtual-columns/


2
Bu doğru cevap. Örneğin, Postgrest'in bu davranışı "hesaplanmış sütunlar" olarak nasıl ifade ettiğini görün .
fiatjaf

Yazım hatası, sanırım - seçim select people.full_name from peopleveya olmalı select full_name(people) from people?
Barguast

Hayır, böyle çalışıyor. "İnsanlardan seçme.full_name" öneki, normal SQL'deki gibi bırakılabilir.
Fabian Zeindl

Bu cevabı kaçırdım, pes ettikten çok sonra geldi. Önerin için teşekkürler.
Manngo

1
Kabul edilen cevabı değiştirebilir misiniz?
Fabian Zeindl

6

Hayır, şu anda (Postgres 9.6'dan itibaren) desteklenmemektedir.

Tek geçici çözüm, indekslemenize gerek olmayan basit bir hesaplama ise bir tetikleyici veya görünüm kullanmaktır.


Sıçanlar. Performansa ihtiyacım olursa materyalize bir görüşe gidebilirim. Yarışmada zaten mevcut olduğu için özellik için bir istek ekledim.
Mart'ta Manngo

1
MVIEW'a gerek yok. Tetikleyicili bir sütun ayrıca sütunun içeriğini dizine
eklemenizi sağlar

Temelde diğer verilerin tekrarı olan ek gerçek sütunları depolamakla ilgili felsefi bir sorunum var. Masayı normalden çıkarır.
17'de Manngo

5
Hesaplanmış bir sütun tam olarak şudur: normalize edilmemiş verilerin depolanması. Hesaplanan sütunun değerinin nasıl oluşturulduğu önemli değildir. Bir "gerçek" hesaplanmış sütun ile bir tetikleyici tarafından oluşturulan bir sütun arasında kavramsal bir fark görmüyorum
a_horse_with_no_name 13:17

Başka bir geçici çözüm (bazı durumlarda) bir ifadeyi dizine eklemektir.
ypercubeᵀᴹ

5

Evet: GENERATED ALWAYS AS … STORED

Postgres 12 , SQL: 2003 standardında belirtildiği gibi oluşturulan sütunlar için işlevsellik ekler .

Değer, INSERTveya sırasında oluşturulur ve UPDATEdaha sonra herhangi bir değer gibi satırla birlikte saklanır.

Oluşturulanlar aynı tablonun temel sütununa veya değişmez bir fonksiyona dayanmalıdır .

Sözdizimi basittir, bir cümle CREATE TABLE:

GENERATED ALWAYS AS ( generation_expr ) STORED 

Misal:

CREATE TABLE people (
    ...,
    height_cm NUMERIC,
    height_in NUMERIC GENERATED ALWAYS AS ( height_cm / 2.54 ) STORED
);

Özellikleri:

  • Dizine eklenebilir.
  • SQL standardının bir parçası.

Uyarılar:

  • Aynı tablonun sütunlarına dayanarak (ilişkili olmayan tablolar)
  • Bölümleme için izin verilmiyor (bölüm anahtarının parçası olamaz)
  • Depolamada yer kaplayan veriler her zaman satırlara yazılır
    • Gelecekteki özellik, depolama olmadan anında hesaplanan değerler için VIRTUAL sunabilir
  • Tek kuşak derinlik (oluşturulan başka bir sütun değil, temel sütun kullanın)
  • DEFAULT TARAFINDAN OLUŞTURULMUŞ bir değer yoktur (değeri geçersiz kılamazsınız)
  • Tetikleyiciden ÖNCE gen-col'ya erişilemiyor (değer henüz belirlenmedi)
  • İşlevler değişmez olmalıdır

Görmek:


Bu bilgi için teşekkürler. Sürüm 12'nin henüz tamamen yayınlanmadığını görüyorum, ancak dört gözle bekliyorum. PostgreSQL'in daha standart sözdizimini kullandığını, ancak MSSQL ile aynı olduğunu unutmayın. SQL2003 teknik özelliklerini burada buldum: sigmodrecord.org/publications/sigmodRecord/0403/… . SQL'in çok yavaş hareket eden bir standart olduğunu ve DBMS uygulamalarının bile yavaş olduğunu söylemiştim .
Manngo

0

Kullanım durumunuza bağlı olarak, yeni bir sütun bildirip ekleme / güncellemede bir tetikleyici ile doldurarak bu tür davranışları başarabilirsiniz.

Zaten sahip olduğunuzdan türetilmiş verileri çoğaltmaktan kaçınmak için mümkünse yukarıdaki cevapları kullanırım, ancak hile yapar ve bir kez hesaplamak ve kaydetmek istediğiniz hesaplama açısından yoğun türetilmiş alanlar için yararlı olabilir.

Bu yaklaşımı, bazen sadece 18 basamaklı bir anahtarın 15 basamağına sahip olduğum (son 3 basamak sadece bir sağlama toplamı) olan bir sorunla başa çıkmayı düşündüm, ancak yabancı anahtar ilişkisini zorlamak istedim.

Tetikleyicilerdeki PG dokümanları: https://www.postgresql.org/docs/9.6/sql-createtrigger.html

W3 örneği: https://www.w3resource.com/PostgreSQL/postgresql-triggers.php

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.