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
- 遷移帶LOB等大欄位資料到非預設表空間
- jpa~為欄位新增insert的預設值
- MySQL欄位預設值設定詳解MySql
- 2.5.9.2 重寫預設表空間型別型別
- MySQL修改欄位預設值MySql
- sql設定欄位預設值SQL
- 【COLUMN】設定表欄位預設值僅對未來生效
- oracle增加欄位帶預設值Oracle
- 查詢oracle欄位預設值Oracle
- MySQL-修改欄位型別、設定預設值,以及新增註釋MySql型別
- SQL新增表欄位SQL
- Oracle11g新特性 - 快速線上新增not null欄位OracleNull
- 對錶中的欄位設定了預設值,新增記錄後卻發現該欄位為nullNull
- PostgreSQL表增加/刪除欄位是否會重寫表SQL
- MySQL多個timestamp欄位自動新增預設值的問題MySql
- 通用SQL語句修改欄位預設值SQL
- 非空+預設值——一種選擇方案思路
- 表中已有資料,將表中某個欄位為空的改為非空
- MySQL為欄位新增預設時間(插入時間)MySql
- SharePoint 多行文字欄位設定預設值
- Oracle 18c新特性詳解 - 表和表空間相關的新特性Oracle
- oracle時間欄位預設值,hibernate對映Oracle
- lob欄位表空間遷移
- Java判斷欄位是否為空,為空賦值 ?Java賦值
- [AX]AX2012開發新特性-禁止表或者表欄位
- Django日期欄位預設值default=timezone.nowDjango
- pydantic 欄位的預設值設定獲取當前時間
- Sqlserver的欄位datetime型別預設值設為getdate()時,設值毫秒為000SQLServer型別
- SQL Server語句刪除帶有預設值的欄位SQLServer
- EBS:主鍵ID欄位預設值來源於序號
- 《NET CLR via C#》---第七章(常量,讀/寫欄位,可讀欄位)C#
- Oracle修改預設表空間和預設臨時表空間Oracle
- 【新炬網路名師大講堂】Oracle中大表新增帶有預設值列的討論(包括11G,12C新特性)Oracle
- oracle大表新增欄位default經驗分享Oracle
- 改變表中非空欄位的型別型別
- GORM 如何讀取別名欄位的值GoORM