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的索引也已经被删除