【轉】《與MySQL的零距離接觸》第三章:約束以及修改資料表 (3-7:MySQL 修改資料表–刪除約束)
3-7:MySQL 修改資料表–刪除約束
一. 前言
上一節最後我們講到了刪除預設約束,本節我們來講解刪除主鍵約束和唯一約束以及外來鍵約束
二. 刪除主鍵約束
刪除主鍵約束的語法結構:
ALTER TABLE tbl_name DROP PRIMARY KEY
因為任何一個數據表只有一個主鍵約束,所以刪除的時候不用加名字:
mysql> ALTER TABLE users2 DROP PRIMARY KEY; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> SHOW COLUMNS FROM users2; +----------+----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+----------------------+------+-----+---------+-------+ | username | varchar(10) | NO | PRI | NULL | | | pid | smallint(5) unsigned | YES | MUL | NULL | | | id | smallint(5) unsigned | NO | | 0 | | | age | tinyint(3) unsigned | NO | | NULL | | +----------+----------------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)
可以看到id已經不再是主鍵約束
三. 刪除唯一約束
刪除唯一約束的語法結構:
ALTER TABLE tbl_name DROP {INDEX | KEY} index_name
因為一張表可以有多個唯一約束,所以刪除的時候需要指定名字,首先需要獲取約束的名字,
可以通過檢視一下user2表的索引來獲取:
mysql> SHOW INDEXES FROM users2\G *************************** 1. row *************************** Table: users2 Non_unique: 0 Key_name: username Seq_in_index: 1 Column_name: username Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: *************************** 2. row *************************** Table: users2 Non_unique: 1 Key_name: pid Seq_in_index: 1 Column_name: pid Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: 2 rows in set (0.00 sec)
Key_name 便是定義的索引名字,接下來我們來刪除唯一約束:
mysql> ALTER TABLE users2 DROP INDEX username;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
注意這裡只是刪除約束,而不是刪除欄位,接下來再來看一下user2表的索引:
mysql> SHOW INDEXES FROM users2\G *************************** 1. row *************************** Table: users2 Non_unique: 1 Key_name: pid Seq_in_index: 1 Column_name: pid Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: 1 row in set (0.00 sec)
發現只剩一個索引,刪除成功。因為建立唯一約束的時候,索引
這裡遇到幾個問題就是:
問:為什麼刪除唯一約束,卻需要唯一索引的名字呢?而且為什麼Column_name :欄位/列名稱 和Key_name:索引名稱相同呢?
答:建立主鍵約束、唯一約束的時候,會自動建立一個唯一的索引。主鍵預設生成的索引名字是PRIMARY,而唯一約束生成的是同名的索引,所以你看到這個key_name(索引名稱)和column_name是同一個名字。 ——摘自Gemma_Tong的回答
問:刪除約束為什麼是DROP INDEX ,index 不是索引麼? 刪除約束為什麼是DROP INDEX ,index 不是索引麼?
答一:如果說我們要刪除一個unique key ,但是這個unique key在一張表中有很多個,這時候我們單純的寫drop unique key系統不知道的要刪除的是哪一個,會全部刪除,這不是我們想要的結果,好在的是每一個約束都存在一個名字,你可以吧把ndex理解成約束的名字,這樣我們就可以指定刪除某個約束了; 檢視INDEX : SHOW INDEXES FROM table name;——摘自greenhandc的回答
答二:在你建立unique約束的同時系統會給你自動建立一個同名的索引,在刪除unique約束的時候你直接去刪除索引就可以了,只有unique約束可以這樣使用。在刪除主鍵和外來鍵的時候還是要刪除約束的,值得注意的是刪除外來鍵之後,由於建立外來鍵的時候系統也自動建立了一個同名索引,刪除外來鍵索引還在,為了避免查詢表結構的時候產生混亂,在刪除外來鍵之後最後順帶著連同索引一起刪除。——摘自大佬金的回答
四. 刪除外來鍵約束
刪除外來鍵約束語法結構:
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol
通過檢視一下user2表的建立命令可以檢視外來鍵約束的名字:
mysql> SHOW CREATE TABLE users2\G
*************************** 1. row ***************************
Table: users2
Create Table: CREATE TABLE `users2` (
`username` varchar(10) NOT NULL,
`pid` smallint(5) unsigned DEFAULT NULL,
`id` smallint(5) unsigned NOT NULL DEFAULT '0',
`age` tinyint(3) unsigned NOT NULL,
KEY `pid` (`pid`),
CONSTRAINT `users2_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `provinces` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
可以看到,外來鍵約束的名字是users2_ibfk_1,這是系統賦予的,接下來刪除外來鍵約束:
mysql> ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE users2\G
*************************** 1. row ***************************
Table: users2
Create Table: CREATE TABLE `users2` (
`username` varchar(10) NOT NULL,
`pid` smallint(5) unsigned DEFAULT NULL,
`id` smallint(5) unsigned NOT NULL DEFAULT '0',
`age` tinyint(3) unsigned NOT NULL,
KEY `pid` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
可以看到外來鍵約束已經被刪除,但是還存在著名為pid的索引,接下來刪除索引:
mysql> SHOW CREATE TABLE users2\G
*************************** 1. row ***************************
Table: users2
Create Table: CREATE TABLE `users2` (
`username` varchar(10) NOT NULL,
`pid` smallint(5) unsigned DEFAULT NULL,
`id` smallint(5) unsigned NOT NULL DEFAULT '0',
`age` tinyint(3) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
可以看到pid的索引也已經被刪除