如果所有列都是必需的,是否应该合并指向同一个表的外键?

ef1yzkbh  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(236)

我经常遇到这种情况。举个例子,
user 唯一标识为 appId, externalUserId .
Contract 有外键 (fileUploadId, appId, externalUserId) 到表 fileUpload 确保文件上载属于指定用户。
Contract 有外键 (businessId, appId, externalUserId) 到表 business 确保业务属于指定用户。
通过以上两种方式,我们保证用户a的文件上传不会被用作用户b业务的合同。 Contract 也有一个 fileTypeId 列,即 STORED GENERATED 到某个值,表示“此合同属于文件类型” XXX_CONTRACT "
Contract 也有外键 (fileUploadId, fileTypeId) 到表 fileUpload .
这保证我们只使用 XXX_CONTRACT 文件上载 Contract ,而不是意外地使用其他文件类型。
鉴于上述情况,我们有两个外键指向同一个表 fileUpload ,甚至有重叠的列,
(fileUploadId, appId, externalUserId) (fileUploadId, fileTypeId) 所有的柱子都是 NOT NULL .
所以,在我看来,把外键组合成一个更大的外键是安全的, (fileUploadId, appId, externalUserId, fileTypeId) 我们仍然会有和以前一样的保证。
我的直觉是,我不应该组合外键,因为通过意义将它们分开,并赋予fks有意义的名称有助于提高可维护性。
但我从未接受过这些东西的正规教育,所以我想知道行业标准是什么。
与此相关的是,合并它们与分离它们是否有性能优势?

8nuwlpux

8nuwlpux1#

但我从未接受过这些东西的正规教育,所以我想知道行业标准是什么。
标准是,没有标准。
如前所述,可以使用多列定义主键。例如,这称为自然主键:用户可以通过名字、姓氏和出生日期进行唯一标识((至少几乎是这样)
这类键通常被称为复合键,因为每一列都不能单独工作,只有将它们组合在一起才能形成主键。
代理(或人工)主键也是众所周知的: id 列,使用自动增量。
所以,对于您的问题:是的,如果您有3列已经形成了一个自然主键,那么添加更多的列是完全安全的。因为已经存在的3列将唯一地标识行,所以在键中添加第4、第5甚至第6列是没有坏处的。
我想说,你是要使用自然主键还是代理主键取决于个人偏好。我从不使用自然键,即使是在可能的table上。
请记住,无论何时需要删除/更新某些内容,都需要知道主键。因此,使用自然键时,需要通过许多方法调用移动多个值,而代理键的优点是只有“一个”id来唯一标识行。不需要更多信息。
就性能而言,我假设(基于整数的)代理主键往往比(基于字符串的)自然主键快。在编写查询和/或设计索引时,需要考虑的列更少。

相关问题