将外键绑定到非主键时是否有任何缺陷?

时间:2016-02-01 19:37:52

标签: sql database database-design foreign-keys

假设我们有一个类似的工作表:

  • job(id,number);

假设我们有一个客户请求来跟踪工作时间,我们创建一个如下表格:

  • (A)job_timer(id,job_id,timestamp);

但我们可以选择如何将其与job表绑定,因此我们也可以:

  • (B)job_timer(id,job_number,timestamp);

假设job_number为UNIQUE

我习惯于根据id创建外键,所以A)job_id将是我看到它完成的方式。但是,客户正在按工作号查找工作,如果我直接通过B)job_number进行查找,它将为我和数据库节省一些工作。但我应该这样做吗?

使用job_id时的更多工作我的意思是,即给定的工作号我只需要使用job_timer表。当给定job_id时,我需要在两个表中绑定 - 更多的认知编程工作,更多的数据库工作。

注意,类似的问题Foreign Key to non-primary key解决了非主键的问题,但我不相信它解决了我的问题。

原始表格(job)是遗留代码库的一部分,其中字段idnumber在整个代码中广泛使用,从这个意义上讲,我有一个“拆分主键” “条件。由于缺乏完整的测试覆盖率,除草将是令人望而却步的。为什么创建number字段以及为什么将其设置为varchar是很好的问题。我相信在某些时候肯定有理由。

我正在寻找类似“是的,继续它完全没问题,在这种情况下没有最佳实践”或“不,如果你这样做,你可能会遇到问题X ,Y,Z在未来“。

1 个答案:

答案 0 :(得分:1)

当p列的值必须显示为{{1 }或FOREIGN KEY列。但是当存在多个CK时,选择哪个CK(候选键)作为FK(外键)引用最终是实用的。该标准基本上是用于选择PK(主键)的标准,因为将CK区分为PK最终用于FK中的优选用途。典型的列表是familiarity, irreducibility, stability & simplicity。过去使用表明CK是合理的。虽然考虑PRIMARY KEY仅用于最终输出,但解释了它的变化及其独特性,尽管存在和UNIQUE NOT NULL的唯一性。如果你曾经同时包含两者,那么请注意在对上声明number可能是合适的。 (要求在id中添加FOREIGN KEY对。)

超级键是一组唯一且不为空的列。 CK是超级密钥,不包含任何较小的超级密钥。一张表可以有任意数量的CK。 PK是一个杰出的CK。

我们可以说是一个外国超级钥匙"当表中的子行的值也是引用表中某些超级键子行的值时保持。如果超级密钥是CK,则外部超级密钥是FK。我们告诉DBMS有关CK和外部超级密钥的信息,以便它可以防止无效的数据库状态。

SQL UNIQUE NOT NULL实际上声明了一个超级密钥。所以SQL job实际上声明了一个杰出的超级密钥。如果超级键是CK,那就是PK。 SQL UNIQUE NOT NULL实际上声明了一个外部超级密钥。如果引用的超级键是CK,则为FK。

你的桌子用"拆分PK"只是一张有两个CK的桌子。 (这形成了一个超级密钥,因为所有CK的超集都是超级密钥。)就约束声明而言,首要性是无关紧要的。您应该声明持有的约束,以便DBMS可以强制执行它们。

请注意,如果您的表格中包含PRIMARY KEY FOREIGN KEY作为FK,那么值可能必须出现在id。如果是,则通过number将该对声明为外部超级密钥。当有自然键时,这种添加外部超级键的缺点是具有代理键的缺点。另一方面,只要有多个CK,就会出现这种情况。

PS任何唯一列集的超集都是唯一的。但SQL要求您将FK的目标声明为job,即使它必须已经是唯一的,因为它包含一些声明为唯一的较小集合。因此,当FOREIGN KEY - UNIQUE NOT NULL对必须出现在id中时,您应该声明化合物FK和复合超级键。 PPS所有这些声明的要点是完整性,而不是用于优化的索引。 (虽然这也很重要。)