让我们想象一下简单的真实世界customer-loan
关系场景,其中没有客户的贷款存在是不可能的,因此关系逻辑上应该多对一识别关系与以下结构:
CREATE TABLE `customer` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50)
) ENGINE = InnoDB;
CREATE TABLE `loan` (
`id` INT NOT NULL AUTO_INCREMENT,
`customer_id` INT NOT NULL,
`amount` FLOAT,
`currency` VARCHAR(10),
PRIMARY KEY (`id`, `customer_id`),
CONSTRAINT `identifying_fk` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`)
) ENGINE = InnoDB;
另一方面,技术上相同的逻辑可以应用多对一非识别强制关系,具有以下结构:
CREATE TABLE `customer` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50)
) ENGINE = InnoDB;
CREATE TABLE `loan` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`customer_id` INT NOT NULL,
`amount` FLOAT,
`currency` VARCHAR(10),
CONSTRAINT `non-identifying_fk` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`)
) ENGINE = InnoDB;
问题:使用识别关系而不是非识别关系有什么优缺点,反之亦然?是否有任何技术偏好选择另一个?
NB。其中一个disadvantage using identifying relationship
是composite PRIMARY KEY
,通常很难维护。
例如PHP Doctrine ORM
不支持对此类复合键进行操作,其中一个id是自动生成的,第二个键(外键)是父实体的标识符。
答案 0 :(得分:3)
如果您有auto_increment
列,则应该是主键。通常,我避免使用复合主键。它们只是在外键定义和连接条件中引入了错误的范围。您还指出了使用其他工具时的限制。
我希望这个问题能为n-m关系。这是复合主键存在良好参数的一种情况。但是,在您的情况下,贷款只有一个客户,因此第二种方法似乎更多"正确"。
答案 1 :(得分:0)
与此同时,我读到了识别关系和非识别关系之间的区别。
在您的示例中,您有多对一的关系。因此,贷款不符合识别关系的条件,因为客户ID不足以识别贷款。因此,这种关系是非识别。
如果每个客户只能获得一笔贷款,那么贷款与客户之间就会存在一对一的关系。客户ID足以识别贷款,因此我们有识别关系。在这种情况下,将loan表的customer_id列设置为主键是一个不错的选择。
识别关系也与多对多关系中的链接表一起使用。