识别与非识别关系的利弊,反之亦然

时间:2017-07-22 13:44:50

标签: php mysql sql foreign-keys relationship

让我们想象一下简单的真实世界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 relationshipcomposite PRIMARY KEY,通常很难维护。

例如PHP Doctrine ORM不支持对此类复合键进行操作,其中一个id是自动生成的,第二个键(外键)是父实体的标识符。

2 个答案:

答案 0 :(得分:3)

如果您有auto_increment列,则应该是主键。通常,我避免使用复合主键。它们只是在外键定义和连接条件中引入了错误的范围。您还指出了使用其他工具时的限制。

我希望这个问题能为n-m关系。这是复合主键存在良好参数的一种情况。但是,在您的情况下,贷款只有一个客户,因此第二种方法似乎更多"正确"。

答案 1 :(得分:0)

与此同时,我读到了识别关系非识别关系之间的区别。

在您的示例中,您有多对一的关系。因此,贷款不符合识别关系的条件,因为客户ID不足以识别贷款。因此,这种关系是非识别

如果每个客户只能获得一笔贷款,那么贷款与客户之间就会存在一对一的关系。客户ID足以识别贷款,因此我们有识别关系。在这种情况下,将loan表的customer_id列设置为主键是一个不错的选择。

识别关系也与多对多关系中的链接表一起使用。