2012-01-14 147 views
155

我有一个名为provider的表。我有三列叫做personplace,thing。可能有重复的人物,重复的地方和重复的事物,但永远不会有重复的人物组合。ALTER TABLE添加一个复合主键

我将如何使用这三列在ALTER TABLE中为MySQL中的此表添加组合主键?

回答

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

如果主键已经存在,那么你要做到这一点

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

这增加了三个独特的PKS,不是一个复合PK。 – David542 2012-01-14 01:29:13

+13

@ David542不,它不 - 你只能有1个主键。 – 2012-01-14 01:30:35

+28

@David:它是由多个字段组成的单个主键,也就是一个组合键。 – 2012-01-14 01:33:35

14

你可能只是想要一个唯一约束。特别是如果你已经有一个代理键。 (例如:一个AUTO_INCREMENT)

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

谢谢,我想要的是一个约束,我不知道在这个最初的帖子中要求什么。感谢您将此添加到线程。 – ZaneDarken 2014-12-12 21:47:57

+0

我通常使用代理键......然后添加一个唯一的约束。这样......如果“唯一性”改变了道路,调整约束并没有太大的戏剧性,与主键相混淆。如果你有一个外键引用这个表的子表,你只需要FK代理键,而不是全部3列。 - – granadaCoder 2014-12-23 14:42:00

3
alter table table_name add primary key (col_name1, col_name2); 
0

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

16

@Adrian康沃尔的答案是正确的。但是,放弃现有主键还有另外一个警告。如果该主键被另一个表用作外键,则在尝试将其删除时会出现错误。在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'; 

乙可以使用ALTER语句1
A中的主键索引可以使用主键索引在ALTER语句2
C可使用任一索引
d不能使用索引

A使用索引2中的前两个字段作为部分索引。 A不能使用索引1,因为它不知道索引的中间位置部分。尽管如此,它仍然可以使用部分索引。

D不能使用任一索引,因为它不知道人。

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

1

它`肯定更好,虽然使用组合唯一关键,因为@GranadaCoder提供的,有点棘手例如:

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