MySQL更改复合主键以替代

时间:2019-02-20 21:29:20

标签: mysql

我有一个名为my_table的表(包含现有数据),在(dealer_id, model_id, model_year, allocation_week)上有一个复合主键,其中dealer_idmodel_id都是{{1 }}和model表。 dealer中没有单个唯一列。我想使用

添加一个新的代理主键
my_table

此操作失败,并显示错误ALTER TABLE my_table ADD COLUMN id INT PRIMARY KEY AUTO_INCREMENT FIRST;

因此,我尝试使用以下方式删除现有(复合)主键:

1068 Multiple primary key defined

失败,说ALTER TABLE my_table DROP PRIMARY KEY;

如何用代理密钥替换组合密钥?

1 个答案:

答案 0 :(得分:1)

再现错误:

mysql> create table dealers (dealer_id int primary key);
mysql> create table models (model_id int primary key);
mysql> create table my_table (dealer_id int, model_id int, model_year int, allocation_week int, primary key (dealer_id, model_id, model_year, allocation_week));

mysql> alter table my_table add foreign key (dealer_id) references dealers(dealer_id);

mysql> alter table my_table add foreign key (model_id) references models (model_id);

现在表格看起来像这样。它为model_id隐式创建了一个索引,但不必为dealer_id进行索引,因为它能够“借用”最左边一列的PK索引。

mysql> show create table my_table\G

CREATE TABLE `my_table` (
  `dealer_id` int(11) NOT NULL DEFAULT '0',
  `model_id` int(11) NOT NULL DEFAULT '0',
  `model_year` int(11) NOT NULL DEFAULT '0',
  `allocation_week` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`dealer_id`,`model_id`,`model_year`,`allocation_week`),
  KEY `model_id` (`model_id`),
  CONSTRAINT `my_table_ibfk_1` FOREIGN KEY (`dealer_id`) REFERENCES `dealers` (`dealer_id`),
  CONSTRAINT `my_table_ibfk_2` FOREIGN KEY (`model_id`) REFERENCES `models` (`model_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

所以当我放弃PK时,它无法做到,因为那样会破坏FK:

mysql> alter table my_table drop primary key;
ERROR 1025 (HY000): Error on rename of './test/#sql-337_18' to './test/my_table' (errno: 150 - Foreign key constraint is incorrectly formed)

解决方案:为dealer_id添加一个二级索引,然后可以删除PK。

您可以在一个ALTER中进行所有这些更改:

mysql> alter table my_table 
    add key (dealer_id), 
    drop primary key, 
    add column id int auto_increment primary key first;

结果:

mysql> show create table my_table\G

CREATE TABLE `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dealer_id` int(11) NOT NULL DEFAULT '0',
  `model_id` int(11) NOT NULL DEFAULT '0',
  `model_year` int(11) NOT NULL DEFAULT '0',
  `allocation_week` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `model_id` (`model_id`),
  KEY `dealer_id` (`dealer_id`),
  CONSTRAINT `my_table_ibfk_1` FOREIGN KEY (`dealer_id`) REFERENCES `dealers` (`dealer_id`),
  CONSTRAINT `my_table_ibfk_2` FOREIGN KEY (`model_id`) REFERENCES `models` (`model_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4