Citus:如何在分布式 tables 列表中添加自引用 table

Citus: How can I add self referencing table in distributed tables list

我正在尝试 运行 create_distributed_table 我需要分片的表,几乎所有表都有自我关系(父子) 但是当我 运行 SELECT create_distributed_table('table-name','id'); 它抛出错误 cannot create foreign key constraint

重现的简单步骤

CREATE TABLE TEST (
  ID        TEXT                 NOT NULL,
  NAME      CHARACTER VARYING(255) NOT NULL,
  PARENT_ID TEXT
);

ALTER TABLE TEST ADD CONSTRAINT TEST_PK PRIMARY KEY (ID);

ALTER TABLE TEST  ADD CONSTRAINT TEST_PARENT_FK FOREIGN KEY (PARENT_ID) REFERENCES TEST (ID);

错误

citus=> SELECT create_distributed_table('test','id');
ERROR:  cannot create foreign key constraint
DETAIL:  Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables

目前,如果不删除自引用外键约束或更改它们以包含一个单独的新分布列,就不可能在 PostgreSQL 上对 table 进行分片。

Citus 根据分布列值的哈希值将记录放入分片。 parent 和 child id 值的哈希值很可能不同,因此记录应该存储在不同的分片中,并且可能存储在不同的工作节点上。 PostgreSQL 没有创建引用不同 PostgreSQL 集群上记录的外键约束的机制。

考虑添加一个新列tenant_id并将该列添加到主键和外键约束中。

CREATE TABLE TEST (
  tenant_id INT                    NOT NULL,
  id        TEXT                   NOT NULL,
  name      CHARACTER VARYING(255) NOT NULL,
  parent_id TEXT                   NOT NULL,

  FOREIGN KEY (tenant_id, parent_id) REFERENCES test(tenant_id, id),
  PRIMARY KEY (tenant_id, id)
);

SELECT create_distributed_table('test','tenant_id');

请注意,parent 和 child 应始终在同一个租户中才能正常工作。