制作 SP 以确定哪些列使 table 独一无二
Crafting a SP to determine which columns make a table unique
出于多种原因,您会想知道哪些列使 table 独一无二。当您有 table 具有实际 PK 或只有几列时,这很容易做到。
但是在这种情况下,我得到了很多巨大的 tables(50 多列),但没有指定任何数据类型,因此没有键。
有一些选项可以获取此信息;使用特定工具解析 table 或简单地询问 table 的 owner/creator 组合键是什么。
这可以证明是一个缓慢的过程。
我想看看是否可以使用存储过程确定 table 的复合键是什么。
我确定每个 table 必须有一个。这是因为每个 table 中的每一行都是唯一的。
我在 google 上花了一些时间在这件事上,但我只遇到了制作复合键等的方法。或者用复合键列出 table 的方法(仅当它们是已经定义)。
基本上我要创建的是一个 SP,它采用 table 名称和 returns 我可以变成复合键的列。
任何人都可以指出我正确的方向,因为我现在有点迷路了。
我在这个项目中使用 SQL 服务器 2014。
我觉得你只需要一个算法。如果您没有 PK,则可以将这些列用作索引中使用的关键嫌疑人。
您必须确保您的组合键是唯一的 table,因此必须查询数据。
这是我的想法:
0.查询table的行数
1.选择一个可疑的列作为唯一键
2.对该列进行字典计数查询,例如前 1000 行
3. 如果结果为1000,则数据唯一。在这种情况下,使用更多行重复查询,直到达到 table 的行数。如果上次查询的结果等于 table 的行数,则您可能找到了唯一键。
4. 如果结果低于 1000,则用另一个怀疑的组合键补充所选列。使用此键从步骤 2 开始重复。
这可能是一项缓慢而乏味的工作,您应该考虑到即使这样,您也不能确定您找到了真正的唯一键,只是一个与现有数据唯一的键。
这不是最适合存储过程的任务,但随着时间的推移它是可行的。不幸的是,直接完整的解决方案需要相当多的时间,太多了,我会说。时间复杂度约为 O(2^C),其中 C 是列数,每次尝试也需要相当多的时间。
完整解决方案的总体思路是迭代列集,table 列的每种可能组合(在集合内没有特定顺序)。然后我们检查耦合集,并从通过测试的那些中得到列数最少的一个。
好消息,可以快速测试可能的解决方案。检查 count(distinct)=count(*)。如果没问题,你至少可以使用整个 table 作为一位密钥...
坏消息,它不能解决问题。
但我们可以贪心
计算每列的唯一值并按降序对列进行排序。如果有简单的 1 列 PK,它将在第一列。
现在我们按此顺序获取列并添加到列集中。如果 selected 列 1..K 的唯一值的乘积小于计数 (*),则无法从中获得唯一索引 - 更进一步。
一旦我们计算出足够多的可能性,尝试使用动态 SQL 在这些列上检查 select 的计数(不同)。如果还不够,再进一步。
一旦我们获得足够的列来涵盖唯一性,我们就快完成了。现在让我们尝试从这个集合中删除一些列。从 1 迭代到 K 并尝试列集 (1..I-1, I+1..K)。如果它仍然是唯一的,请从集合中删除此列并继续删除列。
删除列后继续正确迭代有点棘手,但它是可行的。
一旦我们尝试删除覆盖集的所有列,我们就完成了。
它不是精确的算法,所以你必须手动检查它,但至少你会有一些东西可以开始,它有 O(C*D) 时间复杂度,其中 C 是列数, D 是 table.
中的数据量
这是 ETL 项目中的一个常见问题 - 您获得一个文件、table 或其他数据源,并且必须猜测唯一列、大小、不同值、列之间的关系、可空性等。
SSIS 已经有一个 Data Profiling Task 可以读取源代码(例如 table)并执行许多此类检查。您需要的是Candidate Key Profile
。这将检查哪些列组合可以用作键甚至 近似 键(即不是 100% 唯一)。
这个过程需要很长时间,因为任务必须读取所有数据并检查所有列组合的唯一性。结果保存在可以在 Data Profile Viewer 中打开的文件中进行分析。
您可以一次使用多个配置文件以节省时间,例如一次性收集大小、分布和候选键。
您还可以使用多个分析任务一次分析多个 sources/tables,或将其放入一个循环容器中,以分析文件夹中的所有文件或列表中的所有 table。
出于多种原因,您会想知道哪些列使 table 独一无二。当您有 table 具有实际 PK 或只有几列时,这很容易做到。
但是在这种情况下,我得到了很多巨大的 tables(50 多列),但没有指定任何数据类型,因此没有键。 有一些选项可以获取此信息;使用特定工具解析 table 或简单地询问 table 的 owner/creator 组合键是什么。 这可以证明是一个缓慢的过程。 我想看看是否可以使用存储过程确定 table 的复合键是什么。
我确定每个 table 必须有一个。这是因为每个 table 中的每一行都是唯一的。
我在 google 上花了一些时间在这件事上,但我只遇到了制作复合键等的方法。或者用复合键列出 table 的方法(仅当它们是已经定义)。
基本上我要创建的是一个 SP,它采用 table 名称和 returns 我可以变成复合键的列。
任何人都可以指出我正确的方向,因为我现在有点迷路了。 我在这个项目中使用 SQL 服务器 2014。
我觉得你只需要一个算法。如果您没有 PK,则可以将这些列用作索引中使用的关键嫌疑人。 您必须确保您的组合键是唯一的 table,因此必须查询数据。 这是我的想法: 0.查询table的行数 1.选择一个可疑的列作为唯一键 2.对该列进行字典计数查询,例如前 1000 行 3. 如果结果为1000,则数据唯一。在这种情况下,使用更多行重复查询,直到达到 table 的行数。如果上次查询的结果等于 table 的行数,则您可能找到了唯一键。 4. 如果结果低于 1000,则用另一个怀疑的组合键补充所选列。使用此键从步骤 2 开始重复。
这可能是一项缓慢而乏味的工作,您应该考虑到即使这样,您也不能确定您找到了真正的唯一键,只是一个与现有数据唯一的键。
这不是最适合存储过程的任务,但随着时间的推移它是可行的。不幸的是,直接完整的解决方案需要相当多的时间,太多了,我会说。时间复杂度约为 O(2^C),其中 C 是列数,每次尝试也需要相当多的时间。
完整解决方案的总体思路是迭代列集,table 列的每种可能组合(在集合内没有特定顺序)。然后我们检查耦合集,并从通过测试的那些中得到列数最少的一个。
好消息,可以快速测试可能的解决方案。检查 count(distinct)=count(*)。如果没问题,你至少可以使用整个 table 作为一位密钥...
坏消息,它不能解决问题。
但我们可以贪心
计算每列的唯一值并按降序对列进行排序。如果有简单的 1 列 PK,它将在第一列。
现在我们按此顺序获取列并添加到列集中。如果 selected 列 1..K 的唯一值的乘积小于计数 (*),则无法从中获得唯一索引 - 更进一步。
一旦我们计算出足够多的可能性,尝试使用动态 SQL 在这些列上检查 select 的计数(不同)。如果还不够,再进一步。
一旦我们获得足够的列来涵盖唯一性,我们就快完成了。现在让我们尝试从这个集合中删除一些列。从 1 迭代到 K 并尝试列集 (1..I-1, I+1..K)。如果它仍然是唯一的,请从集合中删除此列并继续删除列。
删除列后继续正确迭代有点棘手,但它是可行的。
一旦我们尝试删除覆盖集的所有列,我们就完成了。
它不是精确的算法,所以你必须手动检查它,但至少你会有一些东西可以开始,它有 O(C*D) 时间复杂度,其中 C 是列数, D 是 table.
中的数据量这是 ETL 项目中的一个常见问题 - 您获得一个文件、table 或其他数据源,并且必须猜测唯一列、大小、不同值、列之间的关系、可空性等。
SSIS 已经有一个 Data Profiling Task 可以读取源代码(例如 table)并执行许多此类检查。您需要的是Candidate Key Profile
。这将检查哪些列组合可以用作键甚至 近似 键(即不是 100% 唯一)。
这个过程需要很长时间,因为任务必须读取所有数据并检查所有列组合的唯一性。结果保存在可以在 Data Profile Viewer 中打开的文件中进行分析。
您可以一次使用多个配置文件以节省时间,例如一次性收集大小、分布和候选键。
您还可以使用多个分析任务一次分析多个 sources/tables,或将其放入一个循环容器中,以分析文件夹中的所有文件或列表中的所有 table。