有没有一种算法方法可以识别postgres中潜在的主键外键关系

问题描述 投票:0回答:1

我在 postgres 中有很多表,每个表有很多列。我需要编写一个程序,使其能够识别可能成为潜在主键和外键对的列。

我现在实现这一目标的方法是迭代每个组合并根据不同的数据比较列。伪代码是这样的:

for(int i=0;i<cols.size;i++)
{
   for(int j=0;j<cols.size;j++)
   {
      if (i != j && (isNotAlreadyVisited(i,j) && isNotAlreadyVisited(j,i)))
      {
            QueryDistinctDataAndCompareCols(i,j)
      }
   }
}

在 QueryDistinctDataAndCompareCols() 方法中,我获取了两个列作为集合的不同值,并获取了列之间的不匹配计数,据此我得出了一个分数,表示它们是否有资格成为 pk-fk 对。

上述方案的问题是迭代次数较多,当列太多、表太多时,会花费太多时间。我还必须在每次迭代中查询数据库以获得列的不同值。

因此,我正在寻找在应用程序层或数据库层中更快且可扩展的解决方案。

在某些情况下,列和表的数量可能分别超过 5000 和 1000,每列超过 5000 个不同值。

postgresql automation foreign-keys primary-key
1个回答
0
投票

您可以添加专用列,就像大多数 ORM 所做的那样:

alter table my_table 
   add column my_uid bigint 
   generated by default as identity primary key;

这比尝试根据基数猜测什么更安全。

即使您遍历整个数据集并确保列中的所有值都是唯一的,或者证明给定的一组字段永远不会重复值的组合,这在将来也可能会出现问题。结果可能是您猜错了,并且您假设唯一标识了一行,这只是暂时的,仅在您的样本中并且只是偶然。

如果您真的想猜测,可以使用

group by cube ()
来检查所有字段组合的计数:

select c1,c2,c3,count(*) from test group by cube(c1,c2,c3)

它仅适用于最多 12 列,但我希望您在使用它之前会耗尽内存。正如您所期望的那样,它会占用大量内存。

您还可以迭代

information_schema.columns
并尝试定义主键和外键工作所需的
unique constraint
,然后记下允许您这样做的组合,丢弃报告
ERROR:  could not create unique index "c1c2" DETAIL:  Key (c1, c2)=(3, 3) is duplicated.

© www.soinside.com 2019 - 2024. All rights reserved.