假设我们有一个类似的工作表:
假设我们有一个客户请求来跟踪工作时间,我们创建一个如下表格:
但我们可以选择如何将其与job
表绑定,因此我们也可以:
假设job_number为UNIQUE
。
我习惯于根据id创建外键,所以A)job_id
将是我看到它完成的方式。但是,客户正在按工作号查找工作,如果我直接通过B)job_number
进行查找,它将为我和数据库节省一些工作。但我应该这样做吗?
使用job_id
时的更多工作我的意思是,即给定的工作号我只需要使用job_timer
表。当给定job_id
时,我需要在两个表中绑定 - 更多的认知编程工作,更多的数据库工作。
注意,类似的问题Foreign Key to non-primary key解决了非主键的问题,但我不相信它解决了我的问题。
原始表格(job
)是遗留代码库的一部分,其中字段id
和number
在整个代码中广泛使用,从这个意义上讲,我有一个“拆分主键” “条件。由于缺乏完整的测试覆盖率,除草将是令人望而却步的。为什么创建number
字段以及为什么将其设置为varchar是很好的问题。我相信在某些时候肯定有理由。
我正在寻找类似“是的,继续它完全没问题,在这种情况下没有最佳实践”或“不,如果你这样做,你可能会遇到问题X ,Y,Z在未来“。
答案 0 :(得分: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所有这些声明的要点是完整性,而不是用于优化的索引。 (虽然这也很重要。)