创建 SP 以确定哪些列使表唯一



出于多种原因,您会想知道哪些列使表格唯一。当您的表具有实际 PK 或只有几列时,这是一项简单的工作。

但是在这种情况下,我得到了很多巨大的表(50 +列),没有指定任何数据类型,因此没有键。 有一些选项可以获取此信息;使用特定工具解析表,或者只是询问表的所有者/创建者组合键是什么。 这可能被证明是一个缓慢的过程。 我想看看我是否可以确定具有存储过程的表的组合键是什么。

我肯定知道每张桌子必须有一个。这是因为每个表中的每一行都是唯一的。

我在谷歌上花了一些时间在这件事上,但我只遇到了制作复合键等的方法。 或者列出具有组合键的表的方法(仅当它们已定义时)。

基本上,我正在尝试创建的是一个SP,它采用表名并返回我可以转换为组合键的列。

谁能指出我正确的方向,因为我现在有点迷茫。 我在这个项目中使用 SQL Server 2014。

对于存储过程来说,这不是最合适的任务,但随着时间的推移,它是可行的。不幸的是,简单完整的解决方案需要相当多的时间,太多了,我会说。时间复杂度约为 O(2^C),其中 C 是列数,每次尝试也需要相当多的时间。

完整解决方案的一般思路是迭代列集,表列的每个可能组合(集合内没有特定的顺序)。然后我们检查耦合集,并从通过测试的耦合中获取列最少

的集合。好消息,对可能的解决方案进行了快速测试。检查计数(不同)=计数(*)。如果没问题,您至少可以将整个表用作一位键...

坏消息,这并不能解决问题。

但我们可以贪婪。

计算每列的唯一值,并按降序对列进行排序。如果有简单的 1 列 PK,它将在第一列中。

现在我们按此顺序获取列并添加到列集。如果所选列 1..K 的唯一值乘法小于 count(*),则无法从中获取唯一索引 - 更进一步。

一旦我们计算了足够多的可能性,请尝试使用动态 SQL 检查这些列的选择的计数(非重复)。如果还不够,那就走得更远。

一旦我们获得了足够的列来覆盖 uniqness,我们就快完成了。现在让我们尝试从此集合中删除一些列。从 1 迭代到 K 并尝试列集 (1..I-1, I+1..K)。如果它仍然唯一,请从集合中删除此列并继续删除列。

删除列后继续正确迭代有点棘手,但这是可行的。

一旦我们尝试删除覆盖集的所有列,我们就完成了。

它不是精确的算法,所以你必须手动检查它,但至少你会有一些东西可以开始,它具有O(C*D)时间复杂度,其中C是列数,D是表中的数据量。

这是 ETL 项目中的常见问题 - 您获得文件、表或其他数据源,并且必须猜测唯一的列、大小、不同值、列之间的关系、可为空性等。

SSIS 已经有一个数据事件探查任务,可以读取源(例如表)并执行其中的许多检查。您需要的是Candidate Key Profile.这将检查哪些列组合可以用作键甚至近似键(即不是 100% 唯一)。

此过程需要很长时间,因为任务必须读取所有数据并检查所有列组合的唯一性。结果保存在可在数据配置文件查看器中打开以进行分析的文件中。

您可以一次使用多个配置文件以节省时间,例如一次性收集大小、分布和候选密钥。

您还可以使用多个分析任务一次分析多个源/表,或将其放在一个循环容器中,该容器分析文件夹中的所有文件或列表中的所有表。

我觉得你只需要一个算法。如果没有 PK,则可以将这些列用作索引中使用的关键嫌疑人。 您必须确保组合键在表上是唯一的,因此必须查询数据。 这是我的想法: 0. 查询表的行数 1. 选择可疑的列作为唯一键 2. 对该列进行字典计数查询,例如前 1000 行 3. 如果结果为 1000,则数据是唯一的。在这种情况下,使用更多的行重复查询,直到达到表的行计数。如果最后一个查询的结果等于表的行计数,则找到可能的唯一键。 4.如果结果低于1000,则用另一个制作复合键的嫌疑人补充所选列。使用此键重复步骤 2。

这可能是一项缓慢而乏味的工作,您应该考虑到,即使这样做,您也无法确定您找到了真正的唯一键,只是一个对现有数据唯一的键。

最新更新