假设我们有一张这样的工作表:
工作(身份证,号码);
假设我们有一个跟踪作业时间的客户请求,并且我们创建了一个这样的表:
(a)作业计时器(id,作业id,时间戳);
但是我们可以选择如何将它绑定到job表,因此我们还可以:
(b)作业计时器(ID、作业编号、时间戳);
假设作业号是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在未来”。

最佳答案

tl;当列列表的值必须显示为另一列FOREIGN KEYPRIMARY KEY列的值时,dr始终声明UNIQUE NOT NULL约束(链)。但是,当存在多个候选密钥时,选择哪个候选密钥作为fk(外键)引用最终是实用的。这些标准本质上是选择pk(主键)的标准,因为将ck区分为pk最终是fks中的首选使用。典型的列表是familiarity, irreducibility, stability & simplicity。这里过去的使用表明,任何一种ck都是合理的。尽管考虑到number只用于最终输出,解释了它的变化性和唯一性,尽管id的存在和唯一性。如果您同时包含这两个值,那么请注意在这两个值上声明FOREIGN KEY可能是合适的。(需要在UNIQUE NOT NULL中的对上添加job
超级键是一组唯一的非空列。ck是一个不包含较小超键的超键。一张桌子可以有任意数量的CK。PK是一种杰出的CK。
我们可以说,当表中的子例程的值也是被引用表中某个超键子例程的值时,“外部超键”将保持不变。如果超级密钥是ck,则外部超级密钥是fk。我们告诉dbms关于cks和外键的信息,这样可以防止数据库状态无效。
sqlUNIQUE NOT NULL实际上声明了一个超键。所以sqlPRIMARY KEY实际上声明了一个可分辨的超键。如果超级密钥是ck,那么它就是pk。sqlFOREIGN KEY实际上声明了一个外键。如果引用的超级键是ck,则为fk。
你的“劈开PK”表只是一张有两个CK的表。(由于ck的所有超集都是超键而形成超键)就约束声明而言,优先级是不相关的。您应该只声明保持的约束,以便dbms可以强制它们。
请注意,如果有一个表将idnumber作为fks,则很可能必须在job中出现成对的值。如果是,则通过FOREIGN KEY将该对声明为外部超级密钥。当存在自然键时,需要添加外部超级键是具有代理键的一个缺点。另一方面,当存在多个CK时,就会出现这种情况。
ps唯一列集的任何超集都是唯一的。但是sql要求您将fk的目标声明为UNIQUE NOT NULL,即使它必须通过包含一些声明为unique的较小集合而已经是唯一的。因此,当有一对必须出现在id中的number-job时,应该声明复合fk和复合超键。PPS的所有这些声明的要点是完整性,而不是用于优化的索引。(尽管这也很重要。)

关于sql - 将外键与非主键绑定(bind)有什么缺点吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35138840/

10-10 06:37