ITPub博客

首页 > 数据库 > PostgreSQL > PG11新特性解读:新增非空默认值字段不需要重写表

PG11新特性解读:新增非空默认值字段不需要重写表

原创 PostgreSQL 作者:yzs87 时间:2020-02-03 17:59:45 1 删除 编辑

1、如何理解这个特性

在postgresql11 之前,为表增加一个包含非空默认值的字段,将会导致表重写,为每一行添加该字段,并填充默认值。如果该表在增加字段前非常大,那么将会非常耗时。

而在11 版本中,新增加一个功能,将不再重写表。而是将非空默认值的属性添加到系统表 pg_attribute 中,该表描述每一列的信息。

 

1 )系统表 pg_attribute 存储所有列信息

postgres=# \d pg_attribute

              Table "pg_catalog.pg_attribute"

    Column     |   Type    | Collation | Nullable | Default

---------------+-----------+-----------+----------+---------

 attrelid      | oid       |           | not null |

 attname       | name      |           | not null |

 atttypid      | oid       |           | not null |

 attstattarget | integer   |           | not null |

 attlen        | smallint  |           | not null |

 attnum        | smallint  |           | not null |

 attndims      | integer   |           | not null |

 attcacheoff   | integer   |           | not null |

 atttypmod     | integer   |           | not null |

 attbyval      | boolean   |           | not null |

 attstorage    | "char"    |           | not null |

 attalign      | "char"    |           | not null |

 attnotnull    | boolean   |           | not null |

 atthasdef     | boolean   |           | not null |

  atthasmissing | boolean   |           | not null |

 attidentity   | "char"    |           | not null |

 attgenerated  | "char"    |           | not null |

 attisdropped  | boolean   |           | not null |

 attislocal    | boolean   |           | not null |

 attinhcount   | integer   |           | not null |

 attcollation  | oid       |           | not null |

 attacl        | aclitem[] |           |          |

 attoptions    | text[]    | C         |          |

 attfdwoptions | text[]    | C         |          |

  attmissingval | anyarray  |           |          |  

Indexes:

    "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname)

"pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum)

 

在表pg_attribute增加了2个字段,atthasmings和attmissingval。如果新增字段有非空默认值,那么atthasmings置为true,attmissingval为默认值。

例如:

postgres=# alter table t1 add column id3 int default 5;

ALTER TABLE

 

postgres=# select atthasmissing,attmissingval from pg_attribute where attrelid=16387 and attname='id3';

 atthasmissing | attmissingval

---------------+---------------

 t             | {5}

(1 row)

 

2)系统表pg_attrdef,存储所有列的默认值,这个表不管是否是alter table添加非空默认值字段

postgres=# \d pg_attrdef

              Table "pg_catalog.pg_attrdef"

 Column  |     Type     | Collation | Nullable | Default

---------+--------------+-----------+----------+---------

 oid     | oid          |           | not null |

 adrelid | oid          |           | not null |

 adnum   | smallint     |           | not null |

 adbin   | pg_node_tree | C         | not null |

Indexes:

    "pg_attrdef_adrelid_adnum_index" UNIQUE, btree (adrelid, adnum)

"pg_attrdef_oid_index" UNIQUE, btree (oid )

 

postgres=# select *from pg_attrdef ;

  oid  | adrelid | adnum |                                                                    adbin                                                                    

-------+---------+-------+---------------------------------------------------------------------------------------------------------------------------------------------

 16390 |   16387 |     3 | {CONST :consttype 23 :consttypmod -1 :constcollid 0 :constlen 4 :constbyval true :constisnull false :location 42 :constvalue 4 [ 5 0 0 0 ]}

(1 row)

 

pg_node_tree是什么数据类型?

 

3)对于表中已存在的行查询时返回attmissingval属性的值, 插入新的行,若指定带默认值字段,则查询时不需要返回attmissingval属性的值,否则需要返回attmissingval属性的值:

postgres=# select *from t1;

 id1 | id2 | id3

-----+-----+-----

   1 |   2 |   5

(1 row)

 

postgres=# insert into t1 values(2,3,NULL);

INSERT 0 1

postgres=# select *from t1;

 id1 | id2 | id3

-----+-----+-----

   1 |   2 |   5

   2 |   3 |    

(2 rows)

 

postgres=# insert into t1 (id1,id2) values(3,4);

INSERT 0 1

postgres=# select *from t1;

 id1 | id2 | id3

-----+-----+-----

   1 |   2 |   5

   2 |   3 |    

   3 |   4 |   5

(3 rows)

 

4)一旦该表被重写(vacuum full table操作),那么 pg_attribute 新增的两个字段值将被清除:

postgres=# select atthasmissing,attmissingval from pg_attribute where attrelid=16387 and attname='id3';

 atthasmissing | attmissingval

---------------+---------------

 f             |

(1 row)

 

但是  pg_attrdef 的值不会清除

postgres=# select *from pg_attrdef ;

  oid  | adrelid | adnum |                                                                    adbin                                                                    

-------+---------+-------+---------------------------------------------------------------------------------------------------------------------------------------------

 16390 |   16387 |     3 | {CONST :consttype 23 :consttypmod -1 :constcollid 0 :constlen 4 :constbyval true :constisnull false :location 42 :constvalue 4 [ 5 0 0 0 ]}

(1 row)


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31493717/viewspace-2674414/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
专注于MySQL、Aerospike、PostgreSQL数据库

注册时间:2017-10-03

  • 博文量
    149
  • 访问量
    285468