我有一个包含许多列的数据库表,并且没有指定的主键。没有超级密钥列表。除了迭代尝试所有候选键/列之外,有没有办法让我使用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来计算我的表中是否可以为我的表创建唯一标识符?
答案 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的列限制。