ALTER TABLE 添加复合主键

Posted

技术标签:

【中文标题】ALTER TABLE 添加复合主键【英文标题】:ALTER TABLE to add a composite primary key 【发布时间】:2012-02-10 04:11:48 【问题描述】:

我有一张名为provider 的表。我有三个名为personplacething 的列。可以有重复的人、重复的地点和重复的事物,但永远不会有重复的人-地点-事物组合。

我将如何 ALTER TABLE 为 mysql 中的该表添加这三列的复合主键?

【问题讨论】:

【参考方案1】:
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);

如果主键已经存在,那么你想这样做

ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);

【讨论】:

@David542 不,它没有 - 你只能有 1 个主键。 @David:它是由多个字段组成的单个主键,也就是复合键。 @David542 当然可以 - 这是一个由 3 个字段组成的复合主键。 3 个字段的组合必须是唯一的。 感谢发帖——真的让我摆脱了与 ui 的斗争 SO 中最宝贵的答案之一 :)【参考方案2】:

@Adrian Cornish 的回答是正确的。但是,删除现有主键还有另一个警告。如果该主键被另一个表用作外键,则在尝试删除它时会出错。在某些版本的 mysql 中,错误消息格式错误(截至 5.5.17,此错误消息仍然

alter table parent  drop column id;
ERROR 1025 (HY000): Error on rename of
'./test/#sql-a04_b' to './test/parent' (errno: 150).

如果您想删除被另一个表引用的主键,您必须先删除另一个表中的外键。如果您在重新创建主键后仍需要该外键,则可以重新创建该外键。

此外,在使用复合键时,顺序也很重要。 这些

1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
and
2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);

不是一回事。 它们都在这三个字段的集合上强制唯一性,但是从索引的角度来看是有区别的。字段的索引从左到右。 例如,考虑以下查询:

A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar';
B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz';
C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar';
D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar';

B可以在ALTER语句1中使用主键索引 A可以在ALTER语句中使用主键索引2 C 可以使用任一索引 D 不能使用任何一个索引

A 使用索引 2 中的前两个字段作为部分索引。 A 不能使用索引 1,因为它不知道索引的中间位置部分。不过,它可能仍然可以在 just person 上使用部分索引。

D 不能使用任何一个索引,因为它不认识人。

有关更多信息,请参阅 mysql 文档here。

【讨论】:

@All - 您能否分享相同的 JPA 等效项?【参考方案3】:

您可能只需要一个唯一约束。特别是如果您已经有代理键。 (已经存在的代理键的示例是一个 AUTO_INCREMENT 的单列)

下面是唯一约束的sql代码

ALTER TABLE `MyDatabase`.`Provider`
    ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;

【讨论】:

谢谢,约束是我想要的,我不知道在最初的帖子中要求什么。感谢您将此添加到线程中。 我通常使用代理键......然后添加唯一约束。这种方式....如果“唯一性”在未来发生变化,那么调整约束并没有太多戏剧性,而不是弄乱主键。如果您有外键引用此表的子表,则只需对代理键进行 FK,而不是全部 3 列。 ——【参考方案4】:
alter table table_name add primary key (col_name1, col_name2);

【讨论】:

【参考方案5】:

使用 COMPOSITE UNIQUE KEY 肯定更好,正如@GranadaCoder 提供的那样,虽然是一个有点棘手的例子:

ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);

【讨论】:

【参考方案6】:

ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);

【讨论】:

以上是关于ALTER TABLE 添加复合主键的主要内容,如果未能解决你的问题,请参考以下文章

尝试插入具有复合主键的记录时出错

mysql的联合主键与复合主键区别

JPA复合主键[重复]

用于更改表添加复合主键的批量 SQL 语句

使用复合主键和注释映射 ManyToMany:

terraform dynamodb 中如何指定复合主键(hashkey)