我正在尝试将伪数据插入到我的数据库中以便进行,并且在一个特定的表中,我有两个列,它们是表的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;
答案 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
约束。外键约束应该始终是主键(除非有一个非常好的理由使用不同的唯一键)。