一种识别PostgreSQL中潜在主键/外键关系的算法方法

suzh9iv8  于 12个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(128)

我在PostgreSQL中有很多表,每个表都有很多列,我需要写一个程序来识别可能是主键和外键对的列。
我迭代了每一个组合,并根据它们不同的数据比较列。伪代码:

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对。
当有太多的列和太多的表时,迭代的次数会花费太多的时间。我还必须在每次迭代中查询DB以获得列的不同值。
在应用层或数据库层中,哪种解决方案更快且可扩展?
在某些情况下,列和表的数量分别可以超过5000和1000,每列可以有超过5000个不同的值。
如果我必须在开始这个处理之前预先计算导出的数据,这是可以接受的。

o7jaxewo

o7jaxewo1#

1.向周围的人询问文档。有人建立了这些表,有可能有一个文档,一个仓库,一个脚本,某人的.psql_history可以告诉你什么是什么。
1.这个问题听起来像是在处理一组没有约束的表,但是没有明确说明,所以可能只需要检查pg_constraint
1.假设以上两种方法都失败了,除了你现在正在做的事情之外,没有其他方法可以做到这一点:提取和比较每列的计数和不同值,或者两者的组合。
1.这些工具的作用是加快速度,而你自己可以做的是抽样。你可以提取1000行或更少的行,并根据这个小子集消除大多数非唯一列:

with samples as (select * from t1 limit 100),
select c1,c2,c3,c4,count(*) from samples 
group by cube(c1,c2,c3,c4) having count(*)>1;

字符串
group by cube ()允许您检查所有字段组合的计数。这使得每个表中只有少数列可作为PK的潜在候选项。
1.一旦有了PK候选项,您就可以遍历information_schema.columns,并尝试定义主键和外键工作所必需的unique constraint,然后记下允许您这样做的组合,丢弃报告ERROR: could not create unique index "c1c2" DETAIL: Key (c1, c2)=(3, 3) is duplicated.的组合
1.一旦你有了PK,你可以在其他表中查找它们

select count(*) from t1 where exists (select from t2 where t1.nonpk=t2.pk);


完成后,确保设置适当的约束,以将所有这些内容固化到XML中并记录下来。

相关问题