我有一个名为provider的表。我有三个栏,分别是人物,地点,事物。可以有重复的人、重复的地点和重复的事物,但永远不可能有重复的人、地点和事物的组合。

我如何ALTER TABLE添加一个复合主键为这个表在MySQL与这三列?


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

如果一个主键已经存在,那么您需要这样做

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

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

下面是唯一约束的sql代码

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

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

删除主键,添加主键(col_name1, col_name2)


@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因为它不知道下标的中间位置。不过,它仍然可以仅对person使用部分索引。

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

更多信息请参阅mysql文档。


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

添加索引idx_name(some_id, another_id, one_more_id)