2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15
開發版本: devel

29.5. 列列表 #

每個釋出可以有選擇地指定要複製到訂閱者的每個表的哪些列。訂閱者端的表必須至少包含已釋出的列。如果未指定列列表,則複製釋出者上的所有列。有關語法的詳細資訊,請參閱 CREATE PUBLICATION

選擇列可以基於行為或效能原因。但是,不要依賴此功能來實現安全:惡意的訂閱者能夠獲取未專門釋出的列中的資料。如果考慮安全性,可以在釋出者端應用保護措施。

如果未指定列列表,則稍後新增到表中的任何列都會自動複製。這意味著具有命名所有列的列列表與根本沒有列列表不同。

列列表只能包含簡單的列引用。列表中列的順序不會保留。

生成的列也可以在列列表中指定。這允許釋出生成的列,而不管釋出引數 publish_generated_columns。有關詳細資訊,請參閱 第 29.6 節

指定列列表時,釋出同時釋出 FOR TABLES IN SCHEMA 不受支援。

對於分割槽表,釋出引數 publish_via_partition_root 決定使用哪個列列表。如果 publish_via_partition_roottrue,則使用根分割槽表的列列表。否則,如果 publish_via_partition_rootfalse(預設),則使用每個分割槽的列列表。

如果釋出釋出 UPDATEDELETE 操作,則任何列列表都必須包含表的副本標識列(請參閱 REPLICA IDENTITY)。如果釋出僅釋出 INSERT 操作,則列列表可以省略副本標識列。

列列表對 TRUNCATE 命令沒有影響。

在初始資料同步期間,僅複製已釋出的列。但是,如果訂閱者來自 15 之前的版本,則在初始資料同步期間會複製表中的所有列,而忽略任何列列表。如果訂閱者來自 18 之前的版本,則初始表同步不會複製生成的列,即使它們已在釋出者中定義。

警告:合併來自多個釋出的列列表

目前不支援由多個釋出組成的訂閱,其中同一表已釋出了不同的列列表。 CREATE SUBSCRIPTION 不允許建立此類訂閱,但仍然可以透過在建立訂閱後修改釋出端的列列表來陷入這種情況。

這意味著更改已訂閱釋出的表的列列表可能會導致訂閱者端引發錯誤。

如果訂閱受到此問題的影響,恢復複製的唯一方法是調整發布端的列列表之一,使其全部匹配;然後重新建立訂閱,或者使用 ALTER SUBSCRIPTION ... DROP PUBLICATION 刪除有問題的釋出之一併重新新增它。

29.5.1. 示例 #

建立一個 t1 表以用於以下示例。

/* pub # */ CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));

建立一個釋出 p1。為表 t1 定義了一個列列表,以減少將要複製的列數。請注意,列列表中列名稱的順序無關緊要。

/* pub # */ CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);

psql 可用於顯示每個釋出的列列表(如果已定義)。

/* pub # */ \dRp+
                                         Publication p1
  Owner   | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root
----------+------------+---------+---------+---------+-----------+-------------------+----------
 postgres | f          | t       | t       | t       | t         | none              | f
Tables:
    "public.t1" (id, a, b, d)

psql 可用於顯示每個表的列列表(如果已定義)。

/* pub # */ \d t1
                 Table "public.t1"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 id     | integer |           | not null |
 a      | text    |           |          |
 b      | text    |           |          |
 c      | text    |           |          |
 d      | text    |           |          |
 e      | text    |           |          |
Indexes:
    "t1_pkey" PRIMARY KEY, btree (id)
Publications:
    "p1" (id, a, b, d)

在訂閱者節點上,建立一個 t1 表,該表現在只需要釋出者表 t1 的一部分列,並建立訂閱 s1 以訂閱釋出 p1

/* sub # */ CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
/* sub # */ CREATE SUBSCRIPTION s1
/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1'
/* sub - */ PUBLICATION p1;

在釋出者節點上,向表 t1 插入一些行。

/* pub # */ INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
/* pub # */ INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
/* pub # */ INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
/* pub # */ SELECT * FROM t1 ORDER BY id;
 id |  a  |  b  |  c  |  d  |  e
----+-----+-----+-----+-----+-----
  1 | a-1 | b-1 | c-1 | d-1 | e-1
  2 | a-2 | b-2 | c-2 | d-2 | e-2
  3 | a-3 | b-3 | c-3 | d-3 | e-3
(3 rows)

只有來自發布 p1 列列表的資料會被複制。

/* sub # */ SELECT * FROM t1 ORDER BY id;
 id |  b  |  a  |  d
----+-----+-----+-----
  1 | b-1 | a-1 | d-1
  2 | b-2 | a-2 | d-2
  3 | b-3 | a-3 | d-3
(3 rows)

提交更正

如果您在文件中看到任何不正確的內容、與您對特定功能的體驗不符或需要進一步說明的內容,請使用 此表單 報告文件問題。