每个发布都可以选择指定每个表中的哪些列复制到订阅端。订阅端上的表必须至少具有所有已发布的列。 如果未指定列列表,则会复制发布端上的所有列。有关语法的详细信息,见CREATE PUBLICATION。
选择哪些列可以基于行为或性能方面的考虑。然而,不要依赖此功能来实现安全性: 恶意订阅端仍然可以获得未被明确发布的列中的数据。如果需要考虑安全性,应在发布端采取保护措施。
如果未指定列列表,那么以后向该表新增的任何列都会自动复制。这意味着,列出全部列的列列表与完全不指定列列表并不相同。
列列表只能包含简单的列引用。列表中列的顺序不会被保留。
当发布还发布 FOR TABLES IN SCHEMA 时,不支持指定列列表。
对于分区表,发布参数publish_via_partition_root 决定使用哪个列列表。如果publish_via_partition_root为true,则使用根分区表的列列表。 否则,如果publish_via_partition_root为false(默认值),则使用各个分区的列列表。
如果某个发布发布UPDATE或DELETE操作, 那么任何列列表都必须包含该表的复制标识列(参见REPLICA IDENTITY)。 如果某个发布只发布INSERT操作,那么列列表可以省略复制标识列。
列列表对TRUNCATE命令没有影响。
在初始数据同步期间,只会复制已发布的列。然而,如果订阅端使用的是 15 之 前的版本,那么在初始数据同步期间会复制表中的所有列,而忽略任何列列表。
目前不支持这样的订阅:它包含多个发布,并且同一张表在这些发布中使用了不同的列列表。 CREATE SUBSCRIPTION会禁止创建这样的订阅,但在订阅创建之后, 仍然可能通过在发布端新增或修改列列表而进入这种情况。
这意味着,更改已被订阅的发布上表的列列表,可能会导致订阅端抛出错误。
如果某个订阅受到了这个问题的影响,那么恢复复制的唯一方法是调整发布端的某个列列表,使它们全部一致; 然后要么重新创建该订阅,要么使用ALTER SUBSCRIPTION ... DROP PUBLICATION 删除一个有问题的发布,再把它重新加回来。
创建一个表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)
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。