首页 > 解决方案 > Citus:如何在分布式表列表中添加自引用表

问题描述

我正在尝试运行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

标签: postgresqlshardingcitus

解决方案


目前,在不删除自引用外键约束或更改它们以包含单独的新分布列的情况下,不可能在 PostgreSQL 上对表进行分片。

Citus 根据分布列值的哈希值将记录放入分片中。最有可能的情况是父 ID 值和子 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');

请注意,父母和孩子应该始终在同一个租户中才能正常工作。


推荐阅读