2012-01-14 142 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);