PG11新特性解讀:新增非空預設值欄位不需要重寫表
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部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2674414/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL技術週刊第9期:PostgreSQL11新特性解讀之新增非空預設值欄位不需要重寫表SQL
- PostgreSQL11preview-新增非空預設值不需要rewritetableSQLView
- jpa~為欄位新增insert的預設值
- MySQL欄位預設值設定詳解MySql
- 2.5.9.2 重寫預設表空間型別型別
- sql設定欄位預設值SQL
- oracle增加欄位帶預設值Oracle
- 查詢oracle欄位預設值Oracle
- PostgreSQL表增加/刪除欄位是否會重寫表SQL
- SharePoint 多行文字欄位設定預設值
- Django日期欄位預設值default=timezone.nowDjango
- Oracle 18c新特性詳解 - 表和表空間相關的新特性Oracle
- MySQL為欄位新增預設時間(插入時間)MySql
- Java判斷欄位是否為空,為空賦值 ?Java賦值
- [20201109]11.2.0.4增加欄位與預設值問題.txt
- Sqlserver的欄位datetime型別預設值設為getdate()時,設值毫秒為000SQLServer型別
- pydantic 欄位的預設值設定獲取當前時間
- 《NET CLR via C#》---第七章(常量,讀/寫欄位,可讀欄位)C#
- EBS:主鍵ID欄位預設值來源於序號
- [20210421]12c以上版本增加欄位與預設值.txt
- fastadmin 新增欄位記圖片欄位AST
- Cache-Control欄位值詳解
- GORM 如何讀取別名欄位的值GoORM
- Oracle12C新特性_不可見欄位(二)Oracle
- 小書MybatisPlus第9篇-常用欄位預設值自動填充MyBatis
- [BUG反饋]新建欄位無法使用字元型預設值字元
- mysql建立表的時候對欄位和表新增COMMENTMySql
- MySQL 更新一個表裡的欄位等於另一個表某欄位的值MySql
- Kubernetes 1.24新特性解讀
- 大咖帶你解讀 PostgreSQL 15 新特性 | 直播預告SQL
- Oracle臨時表空間檢視、新增臨時表空間資料檔案、修改預設臨時表空間 方法!Oracle
- 帝國CMS欄目管理增加自定義欄位值的為空判斷
- PostgreSQL 原始碼解讀(177)- 核心研發#3(如何新增系統欄位)#3SQL原始碼
- PostgreSQL 原始碼解讀(172)- 核心研發#1(如何新增系統欄位)#1SQL原始碼
- PostgreSQL 原始碼解讀(174)- 核心研發#2(如何新增系統欄位)#2SQL原始碼
- Python 3.8 新特性全面解讀Python
- Apache Kyuubi 1.6.0 新特性解讀Apache
- C# 9.0 新特性之引數非空檢查簡化C#