尝试确定数据库表的唯一标识符

时间:2010-12-02 21:18:50

标签: sql

我有一个包含许多列的数据库表,并且没有指定的主键。没有超级密钥列表。除了迭代尝试所有候选键/列之外,有没有办法让我使用SQL来试图确定一个键的子集是否可以为我的表创建一个唯一的标识符?

例如,一个表可能有4列第一个名字,姓氏,地址和zip,我看到的数据是:

John, Smith, 1 main st, 00001  
Mary, Smith, 1 main st, 00001  
Mary, Smith, 2 sub st, 00002

在这种情况下,我需要使用first,last和zip作为我的唯一密钥。

John, Smith, 1 main st, 00001  
John, Smith, 1 main st, 00001

在这种情况下,没有唯一的密钥。

请不要评论我的表格构建和/或数据库的规范化,我只是想找到一个实际的答案。感谢。

这是我的问题:除了迭代尝试所有候选键/列之外,有没有办法让我使用SQL来计算我的表中是否可以为我的表创建唯一标识符?

7 个答案:

答案 0 :(得分:5)

在这种情况下寻找唯一值的子集似乎特定于特定数据集。如果你今天到达一个子集并发现明天无法插入新行怎么办?

使用人工密钥,如自动递增整数。

答案 1 :(得分:4)

简而言之:不,真的没有办法在T-SQL中这样做。

我的建议:只需在表格中添加ID INT IDENTITY PRIMARY KEY列即可。它保证是独一无二的,它会在你创建它时自动填充,它快速而简单,没有杂乱“这是真的独一无二还是有任何违反唯一性的行组合”......

做到这一点 - 这是最简单的方法!!

答案 2 :(得分:3)

您无法找到组合“可以”制作主键。您可以找到一个是否可以为现有数据集创建一个好的主键。

要查找一组字段是否为候选字段,您可以计算这些字段的不同(使用分组汇总)并将其与count (*)进行比较

答案 3 :(得分:2)

如果您要比较两个数据库,那么您可以查看源数据库中是否存在任何重复行,其结构如下:

select a,b,c,d
from mytable
having count(*) > 1
group by a,b,c,d

包括所有列。

然后使用所有列作为“行键”以查看它是否存在于目标系统中

答案 4 :(得分:1)

有一种快得多的方法。

Enterprise dbms已经使用了很多年,但MS SQL Server 2005(2008年可用)以及后来提供了HashBytes()功能。将列转换为CHAR()(MS上的VARCHAR),将它们连接起来;哈希他们;然后比较哈希。您可以在单个SELECT命令中比较这两个表。 IIRC每行最多8000个字符。

(如果您使用此答案,请撤消并重做您的答案选项。)

答案 5 :(得分:0)

此架构中存在更新异常: 你不能不知道他的地址

更好的方法是分成三个表,一个用于人,一个用于PersonAddress

> perons: id,firstname, lastname
> address: id,address:
> personaddress: personid, addressid

答案 6 :(得分:0)

  

您无法找到组合“是否可以”制作主键。

我实际上不同意这一点,我认为可以编写一个查询来从表中选择列的所有可能排列,并将每个排列组合成一个唯一值(最简单,最原始的方法是将它们全部转换为VARCHAR并用间隔字符连接它们 - 一种更好的方法是某种哈希函数。)

通过单次传递,您将拥有一组列,如P1,P12,P123,P2,P23,P3等(如果是三列)。然后,您可以针对每个排列列使用COUNT(*)与COUNT(DISTINCT)进行查询,您将看到哪些排列是唯一的。

使用动态SQL可能会使它可以在任何表上工作,尽管我不知道SQL Server的列限制。