ALTER TABLE 添加复合主键
Posted
技术标签:
【中文标题】ALTER TABLE 添加复合主键【英文标题】:ALTER TABLE to add a composite primary key 【发布时间】:2012-02-10 04:11:48 【问题描述】:我有一张名为provider
的表。我有三个名为person
、place
、thing
的列。可以有重复的人、重复的地点和重复的事物,但永远不会有重复的人-地点-事物组合。
我将如何 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 添加复合主键的主要内容,如果未能解决你的问题,请参考以下文章