PostgreSQL: Değişmez, Uçucu, Kararlı


11

IMMUTABLE, VOLATILE ve STABLE işlevlerinin tanımlarındaki gerçek anlamdan emin değilim.

Belgeleri, özellikle her birinin tanımlarını okudum.

IMMUTABLE, işlevin veritabanını değiştiremeyeceğini ve aynı bağımsız değişken değerleri verildiğinde her zaman aynı sonucu döndürdüğünü gösterir ; yani, veritabanı aramaları yapmaz ya da doğrudan bağımsız değişken listesinde bulunmayan bilgileri kullanmaz. Bu seçenek verilirse, işlevin tüm sabit argümanları olan herhangi bir çağrısı hemen işlev değeri ile değiştirilebilir.

STABLE, işlevin veritabanını değiştiremeyeceğini ve tek bir tablo taramasında aynı bağımsız değişken değerleri için sürekli olarak aynı sonucu döndüreceğini , ancak sonucunun SQL deyimleri arasında değişebileceğini belirtir. Bu, sonuçları veritabanı aramalarına, parametre değişkenlerine (geçerli saat dilimi gibi), vb. Bağlı olan işlevler için uygun seçimdir. (Geçerli komut tarafından değiştirilen satırları sorgulamak isteyen AFTER tetikleyicileri için uygun değildir.) Ayrıca current_timestamp işlev ailesi, değerleri bir işlem içinde değişmediği için kararlı olarak nitelendirilir.

VOLATILE, işlev değerinin tek bir tablo taramasında bile değişebileceğini, dolayısıyla hiçbir optimizasyon yapılamayacağını belirtir. Nispeten az sayıda veritabanı fonksiyonu bu anlamda değişkendir; bazı örnekler random (), currval (), timeofday () şeklindedir. Ancak, yan etkileri olan herhangi bir işlevin, aramaların optimize edilmesini önlemek için, sonucu oldukça öngörülebilir olsa bile, uçucu olarak sınıflandırılması gerektiğini unutmayın; bir örnek setval () şeklindedir.

Karışıklık, her zaman aynı argümanlar göz önüne alındığında, DAİMA veya SÜREKLİ olarak aynı sonucu döndürdüğü DERECE VE KARARLI koşulu ile birlikte gelir .

IMMUTABLE tanımı, işlevin aramaları veritabanı kullanmadığını veya bağımsız değişken listesinde doğrudan bulunmayan bilgileri kullanmadığını belirtir. Yani, bu, bu tür işlevlerin istemci tarafından sağlanan verileri işlemek için kullanıldığı ve SELECT ifadelerine sahip olmaması gerektiği anlamına geliyor ... ancak bu bana biraz garip geliyor.

STABLE ile tanım, tutarlı olarak aynı sonucu döndürmesi gerektiğini söylemesi bakımından benzerdir. Yani, bana göre, bu işlev aynı argümanlarla her çağrıldığında, aynı sonuçları döndürmelidir (her seferinde aynı satırlar).

Yani, benim için ... bu, güncellenebilen bir tablo veya tablolarda SELECT yapan herhangi bir işlevin yalnızca geçici olması gerektiği anlamına gelir.

Ama, yine ... bu bana doğru gelmiyor.

Bunu tekrar kullanım durumuma getirerek, sürekli eklenen tablolarda birden fazla JOIN ile SELECT ifadeleri gerçekleştiren işlevler yazıyorum, böylece işlev çağrıları her seferinde aynı argümanlarda bile farklı sonuçlar döndürmesi bekleniyor .

Bu, işlevlerimin VOLATİL olması gerektiği anlamına mı geliyor? Belgeler nispeten az sayıda veritabanı fonksiyonunun bu anlamda değişken olduğunu göstermesine rağmen ?

Teşekkür ederim!

Yanıtlar:


15

IMMUTABLEsonuçları yalnızca girdilerine bağlı olan saf bir işlev olmalıdır . Bu çok katı bir gerekliliktir; diğer değiştirilemez işlevleri çağıramazlar, tablolara erişemezler, yapılandırma özelliklerinin değerine vb. erişemezler.

STABLEkendileri olan herhangi bir girdiyi kullanabilir STABLE: diğer STABLEveya IMMUTABLEişlevler ve SELECTtablo sorguları. Tabloları sorgulamak güvenlidir, çünkü işlevin bu tablolara ilişkin görünümü sorgunun anlık görüntüsünde değişmez. current_setting(...)Geçerli deyim içinde de atanmayacaklarını bildiğiniz sürece GUC değerlerine ( ) erişebilirsiniz .

VOLATILE fonksiyonlar yukarıdakilere uymayan her şeydir:

  • Yan etkileri olan her şey
  • Yazan her şey
  • PostgreSQL anlık görüntüsü tarafından yönetilmeyen harici verileri sorgulayan her şey
  • ...

Genel olarak, VOLATILEiyi bir nedeniniz olmadığı sürece her şeyi bırakın .

Kullanmanın temel nedeni IMMUTABLE, dizin ifadelerinin bir parçası olarak kullanılacak işlevleri yazarken.


1
"tablolara erişemiyorlar." Adalet içinde yapabilirler ve yaparlar. Daha genel bir kural, tabloların veritabanı yeniden başlatma olmadan anlamlı bir şekilde mutasyona uğramaması gerektiğini düşünüyorum.
Evan Carroll

STABLE tablo erişimine izin veriyorsa, VOLATILE üzerinde / üstünde herhangi bir optimizasyon var mı?
Brooks

Başımın üstünü hatırlamıyorum, dokümanları / kodu kontrol etmek zorunda kalacaksınız.
Craig Ringer

4

STABLE için kalın yazmanız gereken bölüm 'sonuç SQL ifadelerinde değişebilir'

TAŞINMAZ şeylerin hiç değişmemesi gerekiyor. Eğer yeniden Bile, veritabanı sunucusu, çalışma yum update(ama tabii hatalar olabilir!), Senin yapılandırması (gibi değiştirmek datestyle, timezone, default_text_search_config, extra_float_digitsböylece, vs.), ya da eski donanım ile aynı mimari (tamamen sunucu donanım yerini ikili dosyalar hala uyumludur).

Sesi tanımladıkları işlevler STABLE gibi görünür, çünkü tek bir SQL deyimi içinde sorgularını dış sorguyla aynı anlık görüntüyü kullanarak yürütürler ve böylece diğer tablolarda yaptığınız eşzamanlı değişiklikler görünmez. Şimdi, işlevleriniz sunucuya yeni bir bağlantı açarsa ve sorgularını bu bağımsız bağlantıda çalıştırırsa, bu işlev geçici olabilir, çünkü farklı anlık görüntüler kullanırlardı.


IMMUTABLE (hiçbir şey değişemez .... hiç, sorgular, bağlantılar, yeniden başlatmalar, gezegensel imha ve rekonstrüksiyon arasında, veritabanı değiştirilirse BİLE) için önkoşulları anladığım ve VOLATILE (işlev içeriğin dışına atlar) denir). Bu doğru mu? Yani, o zaman STABLE basitçe fonksiyonun veritabanını değiştirmediği ve bağlamının dışında veritabanına erişmediği anlamına gelir? STABLE'ın tanımı gerçekten olması gerekenden daha karmaşık gibi geliyor ... Yoksa bir şeyi dışarıda mı bırakıyorum?
Brooks

PostgreSQL'in aslında bazı sorunları IMMUTABLEve harmanlamaları vardır. glibc(Veya daha yeni Pg'de iconv) harmanlama tanımlarını değiştirmeyeceğine güvenir . Gerçekte, bu değişiklikleri tespit ederler ve hiçbir şekilde tespit edemezler. Sessiz dizin bozulmasına neden olabilir :(. Çoğunlukla farklı işletim sistemi sürümleri arasında çoğaltma yaparken bir sorundur
Craig Ringer
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.