2014-02-14 55 views
6

我有一個這樣的定義的表:修改現有的唯一約束

CREATE TABLE `Message` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    `user_id` integer NOT NULL, 
    `user_to` integer NOT NULL, 
    `top_num` integer NOT NULL, 
    `priority` smallint NOT NULL, 
    `error` varchar(120) NOT NULL, 
    UNIQUE (`user_id`, `user_to`, `top_num`) 
); 

後來,我加入另一列到其對應的MSG_TYPE,就像這樣:

ALTER TABLE Message ADD COLUMN msg_type SMALLINT(6) NOT NULL DEFAULT 0; 

不過,我已經來了意識到我需要將我原來的UNIQUE約束更改爲包含msg_type。我試圖運行

ALTER TABLE Message 
ADD UNIQUE INDEX (`user_id`, `user_to`, `top_num`, `msg_type`); 

但插入到我的表還是失敗,錯誤消息指出,這是因爲舊的唯一性約束失敗。

當我在mysql中調用describe Messages我看到以下內容:

+-----------------+----------------------+------+-----+---------+----------------+ 
| Field   | Type     | Null | Key | Default | Extra   | 
+-----------------+----------------------+------+-----+---------+----------------+ 
| id    | int(11)    | NO | PRI | NULL | auto_increment | 
| user_id   | int(11)    | NO | MUL | NULL |    | 
| user_to   | int(11)    | NO | MUL | NULL |    | 
| top_num   | int(11)    | NO | MUL | NULL |    | 
| priority  | smallint(6)   | NO |  | NULL |    | 
| error   | varchar(120)   | NO |  | NULL |    | 
| msg_type  | smallint(6)   | NO |  | 0  |    | 
+-----------------+----------------------+------+-----+---------+----------------+ 

這使得它看起來像msg_type還真是不約束的一部分......我怎樣才能改變約束,該表的定義與重新創建表格?

+0

閱讀[如何更改外鍵的參照作用?(http://stackoverflow.com/questions/3359329/how -to-change-the-foreign-key-referential-action-behavior/14381227#14381227),同樣你會改變你的唯一約束。 –

+0

請注意,當您丟棄約束條件時,只有constrict被刪除,列不會被刪除。這是MySQL中的兩步工作。 –

+0

所以你沒有命名你約束 –

回答

8

正如在前面的回答to change foreign key constraint使用步驟:

第1步:刪除舊約束:

ALTER TABLE `Message` DROP INDEX `user_id`; 

第2步:新增:

ALTER TABLE `Message` ADD UNIQUE INDEX (
     `user_id`, 
     `user_to`, 
     `top_num`, 
     `msg_type`); 

使用SHOW CREATE TABLE知道約束的名稱:

mysql> SHOW CREATE TABLE `Message` ; 

| Message | CREATE TABLE `Message` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) NOT NULL, 
    `user_to` int(11) NOT NULL, 
    `top_num` int(11) NOT NULL, 
    `priority` smallint(6) NOT NULL, 
    `error` varchar(120) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `user_id` (`user_id`,`user_to`,`top_num`) 
--   ^^^^^^^^^ name 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 

如果你的檢查:

mysql> SHOW INDEX FROM `Message`; 

Key_nameuser_id是在UNIQUE (user_id ....

第一個參數假設,如果你寫:

ALTER TABLE `Message` ADD UNIQUE INDEX ( 
     `user_to`, 
     `user_id`, 
     `top_num`, 
     `msg_type`); 

然後,你必須使用user_to爲下降:

ALTER TABLE `Message` DROP INDEX `user_to`; 
+1

謝謝!這是非常詳細和有益的。特別是「SHOW CREATE TABLE知道約束名稱」的建議,這是非常有用的。我的情況很複雜,其中有些是外鍵,但我會弄明白。 – Catherine

+1

@Catherine歡迎您!記住,當你刪除約束時,列不會被刪除,所以在這個特定的操作中,如果某些字段是外鍵,則不需要打擾。如果你有這些引用的表,那麼你可以暫時禁用fk約束'SET FOREIGN_KEY_CHECKS = 0;'。 –

0

這是因爲要添加唯一索引。請首先刪除唯一索引,然後添加唯一約束。 DROP INDEX index_name ON表名

現在添加唯一約束。

ALTER TABLE Message 
    ADD CONSTRAINT uc_message UNIQUE ((`user_id`, `user_to`, `top_num`, `msg_type`);) 
+0

如何放棄這個問題。 –

+0

DROP INDEX index_name ON表名 –

+0

ALTER TABLE消息DROP UNIQUE INDEX user_id您必須逐個刪除每個索引。 –

0

這是因爲要添加唯一索引。請首先刪除唯一索引,然後添加唯一約束。

ALTER TABLE Message DROP UNIQUE INDEX user_id you have to drop each index one by one. 

現在添加了唯一的約束。 ALTER TABLE消息 ADD CONSTRAINT uc_message UNIQUE((user_iduser_totop_nummsg_type);)