复合键的1列中的重复输入错误

时间:2015-06-22 10:05:55

标签: mysql composite

我正在尝试将伪数据插入到我的数据库中以便进行,并且在一个特定的表中,我有两个列,它们是表的FK和PK。 fk_product_manf_code和fk_content_id。根据我的理解,这些被认为是当前状态的复合键。

所以我将数据添加到表中:

fk_product_manf_code     fk_content_id
NOV-ABC123               1

然后我想将另一个content_id关联到同一个product_manf_code,所以我执行以下操作:

INSERT INTO `mydb`.`package_contents`
(`fk_product_manf_code`, `fk_content_id`)
VALUES
('NOV-ABC123', 2);

但是我遇到了以下错误:

Error Code: 1062. Duplicate entry 'NOV-ABC123' for key 'fk_product_manf_code_UNIQUE'

我不明白发生了什么,因为我认为复合键使2列独一无二?那么,为什么只有一列是独一无二的呢?

这是表CREATE语句

CREATE TABLE `package_contents` (
  `fk_product_manf_code` varchar(255) NOT NULL,
  `fk_content_id` int(11) NOT NULL,
  PRIMARY KEY (`fk_content_id`,`fk_product_manf_code`),
  UNIQUE KEY `fk_content_id_UNIQUE` (`fk_content_id`),
  UNIQUE KEY `fk_product_manf_code_UNIQUE` (`fk_product_manf_code`),
  CONSTRAINT `content_id` FOREIGN KEY (`fk_content_id`) REFERENCES `contents` (`content_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `product_manf_code` FOREIGN KEY (`fk_product_manf_code`) REFERENCES `products` (`product_manf_code`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

1 个答案:

答案 0 :(得分:1)

因此,您正在了解为什么复合主键很痛苦,特别是对于外键约束。整数键不仅效率更高,而且单个键更易于使用。

我建议将表格结构更改为:

CREATE TABLE package_contents (
  package_contents_id int not null auto_increment primary key,
  fk_product_manf_id int NOT NULL,
  fk_content_id int(11) NOT NULL,
  UNIQUE KEY (fk_content_id, fk_product_manf_id),
  CONSTRAINT content_id FOREIGN KEY (fk_content_id)
      REFERENCES contents(content_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT product_manf_code FOREIGN KEY (fk_product_manf_id)
      REFERENCES products(product_manf_id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

请注意,我也将制造商代码更改为id。假设“代码”长于4个字节,这也应该减小表的大小。

如果对所有表执行此操作,数据库将更有效,并且您不需要多余的unique约束。外键约束应该始终是主键(除非有一个非常好的理由使用不同的唯一键)。