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

Postgresql Citus:如何在分布式表列表中添加自引用表,postgresql,sharding,citus,Postgresql,Sharding,Citus,我正在尝试为需要切分的表运行create_distributed_table,几乎所有的表都具有自关系(父-子) 但是当我运行时,选择create_distributed_table('table-name','id') 它抛出错误无法创建外键约束 复制的简单步骤 CREATE TABLE TEST ( ID TEXT NOT NULL, NAME CHARACTER VARYING(255) NOT NULL, PARENT_

我正在尝试为需要切分的表运行
create_distributed_table
,几乎所有的表都具有自关系(父-子) 但是当我运行
时,选择create_distributed_table('table-name','id')
它抛出错误
无法创建外键约束

复制的简单步骤

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);
错误


目前,如果不删除自引用外键约束,或者修改它们以包含一个单独的新分发列,就不可能在PostgreSQL上共享一个表

Citus根据分发列值的散列值将记录放入碎片中。最有可能的情况是,父id值和子id值的散列不同,因此记录应存储在不同的碎片中,并且可能存储在不同的工作节点上。PostgreSQL没有创建引用不同PostgreSQL集群上记录的外键约束的机制

考虑添加一个新列
tenant\u 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');

请注意,父级和子级应该始终位于同一租户中,这样才能工作。

据我所知,分布式表是分片的。不同数据库中表之间的外键应该如何工作?我想说你要么没有约束,要么没有分布式表。@LaurenzAlbe所以这是citus的一个限制,还是与切分有关?我有将近70%的表具有这种嵌套关系,其余30%的表使用分片没有多大好处。我认为这是分片的一个基本属性。切分不仅仅是随机地将部分数据放在不同的存储桶中,还必须进行切分,以便将数据分割成大部分独立的部分。嗯,有道理,但即使分发列不是
Id
,例如
tenent\u Id
,它仍然不允许这种关系。这是因为无法保证原始记录和父记录的
tenant\u Id
值相同。考虑我们有两个(<代码> TANTANGIDID<代码>,<代码> ID <代码>,<代码> PARTRONIDID <代码>三元组:(1100, 200),(2, 200, 300)。由于不同的
租户id
值,父级和子级可以命中不同的碎片,这将破坏外键。Citus很谨慎,在这种情况下不允许fk约束。@MohsinAmjad我添加了一个替代解决方案,并编辑了上面的答案。请检查这是否对您有效是的,有效,因此基本上所有外键约束都必须包括租户id,就像您为家长id添加的一样?假设我有b_id,它是表b的外键,那么约束应该类似于
外键(b_id,tenant_id)引用b(id,tenant_id)
,否则它将不允许?另外,我在您的示例
外键(tenant\u id)引用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');