我是靠谱客的博主 壮观音响,最近开发中收集的这篇文章主要介绍PostgreSQL中函数的三态,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

postgresql中每一个函数都有一个易变性分类,可能是 VOLATILE、STABLE或者IMMUTABLE。 如果CREATEFUNCTION命令没有指定一个分类,则默认是VOLATILE。

VOLATILE函数可以做任何事情,包括修改数据库。在使用相同的参数连续调用时, 它能返回不同的结果

STABLE函数不能修改数据库并且被确保对一个语句中 的所有行用给定的相同参数返 回相同的结果

IMMUTABLE函数不能修改数据库并且被确保用相同的参数 永远返回相同的结果

我们先来看看vlolatile和stable函数的区别,这两者其实比较好区分:简单来说,使用volatile函数在同一个事务中即使是相同的参数,返回的结果也会不同,而stable函数在同一个事务中多次调用返回的值是固定的,比如说我们常见的now和clock_timestamp函数,这两个函数都是获取当前系统的时间,但是now是stable类型的函数,clock_timestamp是volatile类型的.

bill=# /df+ now
                                                                                        List of functions
   Schema   | Name |     Result data type     | Argument data types | Type | Volatility | Parallel |  Owner   | Security | Access privileges | Language | Source code |       Description        
------------+------+--------------------------+---------------------+------+------------+----------+----------+----------+-------------------+----------+-------------+--------------------------
 pg_catalog | now  | timestamp with time zone |                     | func | stable     | safe     | postgres | invoker  |                   | internal | now         | current transaction time
(1 row)

bill=# /df+ clock_timestamp
                                                                                            List of functions
   Schema   |      Name       |     Result data type     | Argument data types | Type | Volatility | Parallel |  Owner   | Security | Access privileges | Language |   Source code   |    Description     
------------+-----------------+--------------------------+---------------------+------+------------+----------+----------+----------+-------------------+----------+-----------------+--------------------
 pg_catalog | clock_timestamp | timestamp with time zone |                     | func | volatile   | safe     | postgres | invoker  |                   | internal | clock_timestamp | current clock time
(1 row)

因此我们在同一个事务中调用这两个函数的值是不一样的!
now:

bill=# begin;
BEGIN
bill=# select now();
              now              
-------------------------------
 2019-09-05 16:56:17.300841+08
(1 row)

bill=# select now();
              now              
-------------------------------
 2019-09-05 16:56:17.300841+08
(1 row)

bill=# select now();
              now              
-------------------------------
 2019-09-05 16:56:17.300841+08
(1 row)

bill=# end;
COMMIT

clock_timestamp:

bill=# begin;
BEGIN
bill=# select clock_timestamp();
        clock_timestamp        
-------------------------------
 2019-09-05 16:56:55.789889+08
(1 row)

bill=# select clock_timestamp();
        clock_timestamp        
-------------------------------
 2019-09-05 16:56:56.629734+08
(1 row)

bill=# select clock_timestamp();
        clock_timestamp        
-------------------------------
 2019-09-05 16:56:57.299359+08
(1 row)

可以看到,在同一个事务中now函数无论调用多少次返回的结果都是一样的,而clock_timestamp函数返回的结果并不一样.

接着我们来看下stable和immutable函数的区别,这两者之间区别相对比较小.一般来说:stable函数在一个语句中给定相同参数返回相同的结果。但是immutable函数却是只要给定相同参数,永远返回相同的结果.所以immutable类型的函数可以用来创建函数索引,而stable函数却不可以.
例子:
创建stable函数:

bill=# create function f_stable(c1 int,c2 int) returns int as $$
bill$# declare
bill$# result int;
bill$# begin 
bill$# select c1+c2 into result;
bill$# return result;
bill$# end;
bill$# $$
bill-# language plpgsql stable;
CREATE FUNCTION

创建immutable函数:

bill=# create function f_immutable(c1 int,c2 int) returns int as $$
bill$# declare
bill$# result int;
bill$# begin 
bill$# select c1+c2 into result;
bill$# return result;
bill$# end;
bill$# $$
bill-# language plpgsql immutable;
CREATE FUNCTION

创建函数索引:

bill=# create index idx_t1 on t1 using btree(f_stable(c1,c2));
psql: ERROR:  functions in index expression must be marked IMMUTABLE

当使用stable函数时会报错.

bill=# create index idx_t1 on t1 using btree(f_immutable(c1,c2));
CREATE INDEX

创建成功,我们再看看该索引能否正常使用呢?

bill=# explain select * from t1 where f_immutable(c1,c2) = 100;
                            QUERY PLAN                             
-------------------------------------------------------------------
 Index Scan using idx_t1 on t1  (cost=0.15..12.05 rows=11 width=8)
   Index Cond: (f_immutable(c1, c2) = 100)
(2 rows)

查询的确可以走索引!

通过以上实验我们可以得到结论:
volatile函数在同一个事务中即使是相同的参数,返回的结果也会不同;
stable函数在同一个事务中对于相同的参数,返回的结果也会相同;
immutable函数却是只要给定相同参数,永远返回相同的结果.

最后

以上就是壮观音响为你收集整理的PostgreSQL中函数的三态的全部内容,希望文章能够帮你解决PostgreSQL中函数的三态所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部