我有一张叫provider
的桌子。我有三个列,分别是person
、place
、thing
。可以有重复的人、重复的地点和重复的事物,但永远不能有重复的人-地-物组合。
我如何修改TABLE,以便在MySQL中使用这三列为该表添加一个复合主键?
发布于 2012-01-14 09:24:58
ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
如果主键已经存在,则需要执行此操作
ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
发布于 2013-10-08 20:56:22
@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 docs here。
发布于 2013-04-16 08:27:56
您可能只是想要一个唯一的约束。特别是如果你已经有一个代理键的话。(已经存在的代理键的示例是作为AUTO_INCREMENT的单个列)
下面是唯一约束的sql代码
ALTER TABLE `MyDatabase`.`Provider`
ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
;
https://stackoverflow.com/questions/8859353
复制相似问题