当前位置:Gxlcms > 数据库问题 > MySQL 约束及修改数据表(三)

MySQL 约束及修改数据表(三)

时间:2021-07-01 10:21:17 帮助过:2人阅读

3、约束以及修改数据表

  • 约束保证数据的完整性和一致性
  • 约束分为表级约束和列级约束

之所以把约束分为表级约束和列级约束,是根据约束所针对的字段的数目来决定的,如果约束只是针对某一个字段,称为列级约束,如果针对两个或以上的字段来使用,称为表级约束。

约束类型包括:

  1. NOT NULL:非空约束
  2. PRIMARY KEY:主键约束
  3. UNIQUE KEY:唯一约束
  4. DEFAULT:默认约束
  5. FOREIGN KEY:外键约束

3.1、MySQL 外键约束的要求解析

外键约束(FOREIGN KEYp):

  • 保证数据的一致性,完整性

  • 实现一对一或一对多关系

3.1.1、外键约束的要求

使用外键约束,只有全部满足以下四个要求时才能使用:

  1. 父表和子表必须使用相同的存储引擎,而且禁止使用临时表
  2. 数据表的存储引擎只能为 InnoDB
  3. 外键列和参照列必须具有相似的数据类型。其中数字的长度或是否有符号位必须相同;而字符的长度则可以不同
  4. 外键列和参照列必须创建索引。如果外键列不存在索引的话,MySQL 将自动创建索引

子表:具有外键列的表

父表:子表所参照的表

外键列:加过 FOREIGN 关键词的列

参照列:外键列所参照的列

3.1.2、编辑数据表的默认存储引擎

修改MySQL 配置文件(my.ini):

打开配置文件,找到 default-storage-engine=INNODB 字段,将默认引擎修改为 INNODB,保存,重启 MySQL 即可。

  1. <code class="language-python">default-storage-engine=INNODB
  2. </code>

查看新建的数据表默认引擎是否为 INNODB:

(一)、数据表 province:

  1. <code class="language-python"># 创建一个名为province的数据表
  2. mysql> CREATE TABLE province(
  3. -> id SMALLINT(5) UNSIGNED PRIMARY KEY AUTO_INCREMENT, # 将 id 设置为主键
  4. -> pname VARCHAR(20) NOT NULL # 省份名称
  5. -> );
  6. Query OK, 0 rows affected (0.06 sec)
  7. # 查看数据表的默认引擎(SHOW CREATE TABLE 表名)
  8. mysql> SHOW CREATE TABLE province;
  9. +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  10. | Table | Create Table |
  11. +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  12. | province | CREATE TABLE `province` (
  13. `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  14. `pname` varchar(20) NOT NULL,
  15. PRIMARY KEY (`id`)
  16. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | # 引擎为 INNODB ,编码方式为 utf8
  17. +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  18. 1 row in set (0.01 sec)
  19. </code>

(二)、数据表 users:

  1. <code class="language-python"># 创建一个名为 users 的数据表
  2. mysql> CREATE TABLE users(
  3. -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  4. -> username VARCHAR(10) NOT NULL,
  5. -> pid BIGINT, # pid 为外键列,pid 的数据类型为 BIGINT,与参照列(id)的数据类型不一致
  6. -> FOREIGN KEY(pid) REFERENCES province (id) # province 中的 id 为参照列
  7. -> );
  8. ERROR 1215 (HY000): Cannot add foreign key constraint
  9. mysql> CREATE TABLE users(
  10. -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  11. -> username VARCHAR(10) NOT NULL,
  12. -> pid SMALLINT UNSIGNED, # pid 为外键列
  13. -> FOREIGN KEY (pid) REFERENCES province (id) # province 中的 id 为参照列
  14. -> );
  15. Query OK, 0 rows affected (0.04 sec)
  16. </code>
  • 上面,创建了两个数据表,分别为存储省份的的数据表(province),以及存储用户的的数据表(users),province 有两个列(idpname(省份名称)),其中 id 设置为主键约束,并自动创建索引,数据类型为 SMALLINT
  • users 有三个列,(idusername、以及 pid),其中 pid 列它参照 provinceid 列(命令为:FOREIGN KEY (pid) REFERENCES province (id)),为此,我们知道了 province 为父表,users 为子表,province-id 为参照列,users-id 为外键列,根据外键约束要求,外键列的数据类型必须与参照列一致,否则无法创建成功。
  • 要使用外键约束就需要满足四个要求,因为 MySQL 的默认存储引擎为 INNODB, 所以 要求 1、2 符合
  • 外键列和参照列的数据类型都为 SMALLINT UNSIGNED,要求 3 符合
  • 参照列(province-id),因为将它设置为主键(PRIMARY KEY)并有(AUTO_INCREMENT),所有有索引
  1. <code class="language-python"># 查看数据表 province id 的索引
  2. mysql> SHOW INDEXES FROM province\G;
  3. *************************** 1. row ***************************
  4. Table: province
  5. Non_unique: 0
  6. Key_name: PRIMARY # 主键约束
  7. Seq_in_index: 1 # 索引(sequence_in_index)
  8. Column_name: id # 列名
  9. Collation: A
  10. Cardinality: 0
  11. Sub_part: NULL
  12. Packed: NULL
  13. Null:
  14. Index_type: BTREE
  15. Comment:
  16. Index_comment:
  17. 1 row in set (0.01 sec)
  18. # 另一种查看方式
  19. mysql> SHOW INDEXES FROM province;
  20. +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  21. | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
  22. +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  23. | province | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
  24. +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  25. 1 row in set (0.00 sec)
  26. # users 也创建了索引,2个索引,id 为主键约束,pid 为外键约束
  27. mysql> SHOW INDEXES FROM users\G;
  28. *************************** 1. row ***************************
  29. Table: users
  30. Non_unique: 0
  31. Key_name: PRIMARY
  32. Seq_in_index: 1
  33. Column_name: id
  34. Collation: A
  35. Cardinality: 0
  36. Sub_part: NULL
  37. Packed: NULL
  38. Null:
  39. Index_type: BTREE
  40. Comment:
  41. Index_comment:
  42. *************************** 2. row ***************************
  43. Table: users
  44. Non_unique: 1
  45. Key_name: pid
  46. Seq_in_index: 1
  47. Column_name: pid
  48. Collation: A
  49. Cardinality: 0
  50. Sub_part: NULL
  51. Packed: NULL
  52. Null: YES
  53. Index_type: BTREE
  54. Comment:
  55. Index_comment:
  56. 2 rows in set (0.01 sec)
  57. </code>

3.2、外键约束的参照操作

  1. CASCADE:从父表删除或更新且自动删除或更新子表中匹配的行
  2. SET NULL:从父表删除或更新行,并设置子表中的外键列为空,如果使用该选项,必须保证子表列没有指定 NOT NULL
  3. RESTRICT:拒绝对父表的删除或更新操作
  4. NOT ACTION:标准 SQL 的关键字,在 MySQL 中与 RESTRICT 相同

给子表中添加 CASCADE 字段:

  1. <code class="language-python"># 创建一个子表 users1
  2. mysql> CREATE TABLE users1(
  3. -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  4. -> username VARCHAR(10) NOT NULL,
  5. -> pid SMALLINT UNSIGNED,
  6. -> FOREIGN KEY (pid) REFERENCES province (id) ON DELETE CASCADE # 将pid设置为外键,并添加 CASCADE 字段
  7. -> );
  8. Query OK, 0 rows affected (0.06 sec)
  9. # 查看 users1
  10. mysql> SHOW CREATE TABLE users1;
  11. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  12. | Table | Create Table |
  13. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  14. | users1 | CREATE TABLE `users1` (
  15. `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  16. `username` varchar(10) NOT NULL,
  17. `pid` smallint(5) unsigned DEFAULT NULL,
  18. PRIMARY KEY (`id`),
  19. KEY `pid` (`pid`),
  20. CONSTRAINT `users1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`) ON DELETE CASCADE
  21. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  22. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  23. 1 row in set (0.01 sec)
  24. # 给父表代表省份名称(pname)的列,插入三条记录(A/B/C)
  25. mysql> INSERT province(pname) VALUES(‘A‘);
  26. Query OK, 1 row affected (0.01 sec)
  27. mysql> INSERT province(pname) VALUES(‘B‘);
  28. Query OK, 1 row affected (0.01 sec)
  29. mysql> INSERT province(pname) VALUES(‘C‘);
  30. Query OK, 1 row affected (0.00 sec)
  31. # 查看插入记录(province)
  32. mysql> SELECT * FROM province;
  33. +----+-------+
  34. | id | pname |
  35. +----+-------+
  36. | 1 | A |
  37. | 2 | B |
  38. | 3 | C |
  39. +----+-------+
  40. 3 rows in set (0.00 sec)
  41. # 给子表插入三条记录
  42. mysql> INSERT users1(username,pid) VALUES(‘Tom‘,1);
  43. Query OK, 1 row affected (0.01 sec)
  44. mysql> INSERT users1(username,pid) VALUES(‘Rose‘,2);
  45. Query OK, 1 row affected (0.01 sec)
  46. mysql> INSERT users1(username,pid) VALUES(‘Alice‘,3);
  47. Query OK, 1 row affected (0.00 sec)
  48. # 查看插入记录(users1)
  49. mysql> SELECT * FROM users1;
  50. +----+----------+------+
  51. | id | username | pid |
  52. +----+----------+------+
  53. | 1 | Tom | 1 |
  54. | 2 | Rose | 2 |
  55. | 3 | Alice | 3 |
  56. +----+----------+------+
  57. 3 rows in set (0.00 sec)
  58. </code>

需要注意的是,在插入记录时,首先要先插入父表,再插入子表,因为子表是参照父表来的。

删除或更新父表中的行,将也会删除子表中匹配的行:

  1. <code class="language-python"># 删除 province 中 id 为 3 的 行
  2. mysql> DELETE FROM province WHERE id=3;
  3. Query OK, 1 row affected (0.01 sec)
  4. # 查看记录,发现 3 被删除了
  5. mysql> SELECT * FROM province;
  6. +----+-------+
  7. | id | pname |
  8. +----+-------+
  9. | 1 | A |
  10. | 2 | B |
  11. +----+-------+
  12. 2 rows in set (0.00 sec)
  13. # 查看 子表users1 中 与 3 匹配的行也被删除了
  14. mysql> SELECT * FROM users1;
  15. +----+----------+------+
  16. | id | username | pid |
  17. +----+----------+------+
  18. | 1 | Tom | 1 |
  19. | 2 | Rose | 2 |
  20. +----+----------+------+
  21. 2 rows in set (0.00 sec)
  22. </code>

在外键约束当中,在实际的开发过程中,我们很少使用物理的外键约束,很多都去使用逻辑的外键约束,因为物理的外键约束只有INNODB这种引擎才会支持,像我们另外的一种引擎MYISAM的引擎则不支持,反过来说,如果我想创建的数据表,假设存储引擎为MYISAM,而且又想使用外键约束的话,其实是不可能实现的,所以说,我们在实际的项目开发中,我们不去定义物理的外键,所谓的逻辑外键指的是就是我们在定义两张表的结构的时候,我们是按照存在的某种结构的方式去定义,但是不去使用FOREIGN KEY这个关键词来定义。

3.3.、表级约束与列级约束

  • 约束按功能划分,分为主键、唯一、默认和外键等。
  • 按照数据列数目的多少,可以将约束分成表级和列级约束。
  • 列级约束:对一个数据列建立的约束,它可以在列定义时声明,也可以在列定义后声明
  • 表级约束:对多个数据列建立的约束,只能在列定义后声明。
  • 列级比表级用的多(实际开发中),如 NOT NULLDEFAULT 约束不存在表级

3.4、修改数据表(添加/删除)

3.4.1、添加单列

  1. <code class="language-python"># 如果省略[FIRST | AFTER col_name],那么添加的列将是在最后
  2. # 也可以选择 FIRST 或 AFTER ,在哪列之前或之后
  3. # 要添加到所有列之前,只需使用命令:.... FIRST;即可
  4. ALTER TABLE tbl_name ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name]
  5. </code>

示例:

  1. <code class="language-python"># 查看 users1 的数据表结构
  2. mysql> SHOW COLUMNS FROM users1;
  3. +----------+----------------------+------+-----+---------+----------------+
  4. | Field | Type | Null | Key | Default | Extra |
  5. +----------+----------------------+------+-----+---------+----------------+
  6. | id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
  7. | username | varchar(10) | NO | | NULL | |
  8. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  9. +----------+----------------------+------+-----+---------+----------------+
  10. 3 rows in set (0.00 sec)
  11. # 添加 age 列
  12. mysql> ALTER TABLE users1 ADD age TINYINT UNSIGNED NOT NULL DEFAULT 10;
  13. Query OK, 0 rows affected (0.12 sec)
  14. Records: 0 Duplicates: 0 Warnings: 0
  15. # age 列排在最后
  16. mysql> SHOW COLUMNS FROM users1;
  17. +----------+----------------------+------+-----+---------+----------------+
  18. | Field | Type | Null | Key | Default | Extra |
  19. +----------+----------------------+------+-----+---------+----------------+
  20. | id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
  21. | username | varchar(10) | NO | | NULL | |
  22. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  23. | age | tinyint(3) unsigned | NO | | 10 | |
  24. +----------+----------------------+------+-----+---------+----------------+
  25. 4 rows in set (0.00 sec)
  26. # 将 password 列添加到 username之后
  27. mysql> ALTER TABLE users1 ADD password VARCHAR(32) NOT NULL AFTER username;
  28. Query OK, 0 rows affected (0.11 sec)
  29. Records: 0 Duplicates: 0 Warnings: 0
  30. # 查看数据表结构
  31. mysql> SHOW COLUMNS FROM users1;
  32. +----------+----------------------+------+-----+---------+----------------+
  33. | Field | Type | Null | Key | Default | Extra |
  34. +----------+----------------------+------+-----+---------+----------------+
  35. | id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
  36. | username | varchar(10) | NO | | NULL | |
  37. | password | varchar(32) | NO | | NULL | |
  38. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  39. | age | tinyint(3) unsigned | NO | | 10 | |
  40. +----------+----------------------+------+-----+---------+----------------+
  41. 5 rows in set (0.00 sec)
  42. </code>

3.4.2、添加多列

添加多列,不可以指定位置关系,只能位于最后

  1. <code class="language-python">ALTER TABLE tbl_name ADD [COLUMN] (col_name column_definition,...)
  2. </code>

3.4.3、删除列

  1. <code class="language-python">ALTER TABLE tbl_name DROP [COLUMN] col_name
  2. </code>

删除单、多列:

  1. <code class="language-python"># 删除多列,只需添加个逗号,后面再加 DROP col_name即可
  2. mysql> ALTER TABLE users1 DROP password,DROP age; # 在删除的同时也可以添加列
  3. Query OK, 0 rows affected (0.12 sec)
  4. Records: 0 Duplicates: 0 Warnings: 0
  5. # 查看数据表结构
  6. mysql> SHOW COLUMNS FROM users1;
  7. +----------+----------------------+------+-----+---------+----------------+
  8. | Field | Type | Null | Key | Default | Extra |
  9. +----------+----------------------+------+-----+---------+----------------+
  10. | id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
  11. | username | varchar(10) | NO | | NULL | |
  12. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  13. +----------+----------------------+------+-----+---------+----------------+
  14. 3 rows in set (0.00 sec)
  15. </code>

3.4.4、添加约束

原有的列上,有的有约束,有的没有,为此我们也可以给没有约束的添加约束,有约束的删除约束:

(1)、添加主键约束:

  1. <code class="language-python">ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] PROMARY KEY [index_type] [index_col_name,...]
  2. </code>

示例:

  1. <code class="language-python"># 首先创建了一个数据表 users2,设置了2列,然后再添加一列(id),3个列都没有设置约束,现在我们要将 id 设置为主键约束
  2. # 创建数据表 users2
  3. mysql> CREATE TABLE users2(
  4. -> username VARCHAR(10) NOT NULL,
  5. -> pid SMALLINT(5) UNSIGNED
  6. -> );
  7. Query OK, 0 rows affected (0.04 sec)
  8. # 查看数据表结构
  9. mysql> SHOW COLUMNS FROM users2;
  10. +----------+----------------------+------+-----+---------+-------+
  11. | Field | Type | Null | Key | Default | Extra |
  12. +----------+----------------------+------+-----+---------+-------+
  13. | username | varchar(10) | NO | | NULL | |
  14. | pid | smallint(5) unsigned | YES | | NULL | |
  15. +----------+----------------------+------+-----+---------+-------+
  16. 2 rows in set (0.00 sec)
  17. # 添加 id 列
  18. mysql> ALTER TABLE users2 ADD id SMALLINT UNSIGNED;
  19. Query OK, 0 rows affected (0.07 sec)
  20. Records: 0 Duplicates: 0 Warnings: 0
  21. # 查看数据表结构
  22. mysql> SHOW COLUMNS FROM users2;
  23. +----------+----------------------+------+-----+---------+-------+
  24. | Field | Type | Null | Key | Default | Extra |
  25. +----------+----------------------+------+-----+---------+-------+
  26. | username | varchar(10) | NO | | NULL | |
  27. | pid | smallint(5) unsigned | YES | | NULL | |
  28. | id | smallint(5) unsigned | YES | | NULL | |
  29. +----------+----------------------+------+-----+---------+-------+
  30. 3 rows in set (0.00 sec)
  31. # 给 id 添加主键约束,可以给添加的约束取别名(这里为 PK_users2_id )
  32. mysql> ALTER TABLE users2 ADD CONSTRAINT PK_users2_id PRIMARY KEY(id);
  33. Query OK, 0 rows affected (0.07 sec)
  34. Records: 0 Duplicates: 0 Warnings: 0
  35. # 查看数据表结构(id 已被定义为主键约束)
  36. mysql> SHOW COLUMNS FROM users2;
  37. +----------+----------------------+------+-----+---------+-------+
  38. | Field | Type | Null | Key | Default | Extra |
  39. +----------+----------------------+------+-----+---------+-------+
  40. | username | varchar(10) | NO | | NULL | |
  41. | pid | smallint(5) unsigned | YES | | NULL | |
  42. | id | smallint(5) unsigned | NO | PRI | NULL | |
  43. +----------+----------------------+------+-----+---------+-------+
  44. 3 rows in set (0.00 sec)
  45. </code>

(2)、添加唯一约束:

  1. <code class="language-python">ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] [index_col_name,...]
  2. </code>

示例:

  1. <code class="language-python"># 给 username 列添加唯一约束
  2. mysql> ALTER TABLE users2 ADD UNIQUE(username);
  3. Query OK, 0 rows affected (0.02 sec)
  4. Records: 0 Duplicates: 0 Warnings: 0
  5. # 查看数据表结构
  6. mysql> SHOW COLUMNS FROM users2;
  7. +----------+----------------------+------+-----+---------+-------+
  8. | Field | Type | Null | Key | Default | Extra |
  9. +----------+----------------------+------+-----+---------+-------+
  10. | username | varchar(10) | NO | UNI | NULL | |
  11. | pid | smallint(5) unsigned | YES | | NULL | |
  12. | id | smallint(5) unsigned | NO | PRI | NULL | |
  13. +----------+----------------------+------+-----+---------+-------+
  14. 3 rows in set (0.00 sec)
  15. </code>

(3)、添加外键约束:

  1. <code class="language-python">ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition
  2. </code>

示例:

  1. <code class="language-python"># 给 pid 添加外键约束,参照列为 province 的 id
  2. mysql> ALTER TABLE users2 ADD FOREIGN KEY (pid) REFERENCES province (id);
  3. Query OK, 0 rows affected (0.09 sec)
  4. Records: 0 Duplicates: 0 Warnings: 0
  5. # 查看数据表结构
  6. mysql> SHOW COLUMNS FROM users2;
  7. +----------+----------------------+------+-----+---------+-------+
  8. | Field | Type | Null | Key | Default | Extra |
  9. +----------+----------------------+------+-----+---------+-------+
  10. | username | varchar(10) | NO | UNI | NULL | |
  11. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  12. | id | smallint(5) unsigned | NO | PRI | NULL | |
  13. +----------+----------------------+------+-----+---------+-------+
  14. 3 rows in set (0.00 sec)
  15. # 查看数据表
  16. mysql> SHOW CREATE TABLE users2;
  17. +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  18. | Table | Create Table |
  19. +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  20. | users2 | CREATE TABLE `users2` (
  21. `username` varchar(10) NOT NULL,
  22. `pid` smallint(5) unsigned DEFAULT NULL,
  23. `id` smallint(5) unsigned NOT NULL,
  24. PRIMARY KEY (`id`),
  25. UNIQUE KEY `username` (`username`),
  26. KEY `pid` (`pid`),
  27. CONSTRAINT `users2_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`) # 外键约束添加成功
  28. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  29. +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  30. 1 row in set (0.00 sec)
  31. </code>

(4)、添加/删除默认约束:

  1. <code class="language-python">ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  2. </code>

示例:

  1. <code class="language-python"># 我们添加了一列 age,再添加默认约束,值为15,再删除
  2. # 添加 age 列
  3. mysql> ALTER TABLE users2 ADD age TINYINT UNSIGNED NOT NULL;
  4. Query OK, 0 rows affected (0.07 sec)
  5. Records: 0 Duplicates: 0 Warnings: 0
  6. # 查看数据表结构
  7. mysql> SHOW COLUMNS FROM users2;
  8. +----------+----------------------+------+-----+---------+-------+
  9. | Field | Type | Null | Key | Default | Extra |
  10. +----------+----------------------+------+-----+---------+-------+
  11. | username | varchar(10) | NO | UNI | NULL | |
  12. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  13. | id | smallint(5) unsigned | NO | PRI | NULL | |
  14. | age | tinyint(3) unsigned | NO | | NULL | |
  15. +----------+----------------------+------+-----+---------+-------+
  16. 4 rows in set (0.00 sec)
  17. # 给 age 设置默认约束(值为15)
  18. mysql> ALTER TABLE users2 ALTER age SET DEFAULT 15;
  19. Query OK, 0 rows affected (0.01 sec)
  20. Records: 0 Duplicates: 0 Warnings: 0
  21. # 查看数据表结构
  22. mysql> SHOW COLUMNS FROM users2;
  23. +----------+----------------------+------+-----+---------+-------+
  24. | Field | Type | Null | Key | Default | Extra |
  25. +----------+----------------------+------+-----+---------+-------+
  26. | username | varchar(10) | NO | UNI | NULL | |
  27. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  28. | id | smallint(5) unsigned | NO | PRI | NULL | |
  29. | age | tinyint(3) unsigned | NO | | 15 | |
  30. +----------+----------------------+------+-----+---------+-------+
  31. 4 rows in set (0.00 sec)
  32. # 删除 age 列的默认约束
  33. mysql> ALTER TABLE users2 ALTER age DROP DEFAULT;
  34. Query OK, 0 rows affected (0.01 sec)
  35. Records: 0 Duplicates: 0 Warnings: 0
  36. # 查看数据表结构
  37. mysql> SHOW COLUMNS FROM users2;
  38. +----------+----------------------+------+-----+---------+-------+
  39. | Field | Type | Null | Key | Default | Extra |
  40. +----------+----------------------+------+-----+---------+-------+
  41. | username | varchar(10) | NO | UNI | NULL | |
  42. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  43. | id | smallint(5) unsigned | NO | PRI | NULL | |
  44. | age | tinyint(3) unsigned | NO | | NULL | |
  45. +----------+----------------------+------+-----+---------+-------+
  46. 4 rows in set (0.00 sec)
  47. </code>

3.4.5、删除约束

(1)、删除主键约束:

  1. <code class="language-python"># 删除主键约束时,不需要指定列名,因为一个数据表中,有且仅有一个主键约束
  2. ALTER TABLE tbl_name DROP PRIMARY KEY
  3. </code>

(2)、删除唯一约束:

  1. <code class="language-python">ALTER TABLE tbl_name DROP {INDEX|KEY} index_name(索引名字)
  2. # 需要注意的是,删除的是约束而不是字段(列),所以需要指定索引名字
  3. </code>

示例:

  1. <code class="language-python"># 查看users2结构,username 有个唯一约束(PRI),首先我们找到约束的索引名字(Key_name),再根据索引名字删除约束
  2. # 查看数据表结构
  3. mysql> SHOW COLUMNS FROM users2;
  4. +----------+----------------------+------+-----+---------+-------+
  5. | Field | Type | Null | Key | Default | Extra |
  6. +----------+----------------------+------+-----+---------+-------+
  7. | username | varchar(10) | NO | PRI | NULL | |
  8. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  9. | id | smallint(5) unsigned | NO | | NULL | |
  10. | age | tinyint(3) unsigned | NO | | NULL | |
  11. +----------+----------------------+------+-----+---------+-------+
  12. 4 rows in set (0.00 sec)
  13. # 查看索引结构
  14. mysql> SHOW INDEXES FROM users2;
  15. +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  16. | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
  17. +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  18. | users2 | 0 | username | 1 | username | A | 0 | NULL | NULL | | BTREE | | |
  19. | users2 | 1 | pid | 1 | pid | A | 0 | NULL | NULL | YES | BTREE | | |
  20. +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
  21. 2 rows in set (0.00 sec)
  22. # 查看索引结构,以网盘的形式显示
  23. mysql> SHOW INDEXES FROM users2\G;
  24. *************************** 1. row ***************************
  25. Table: users2
  26. Non_unique: 0
  27. Key_name: username # 索引名字为(username)
  28. Seq_in_index: 1
  29. Column_name: username
  30. Collation: A
  31. Cardinality: 0
  32. Sub_part: NULL
  33. Packed: NULL
  34. Null:
  35. Index_type: BTREE
  36. Comment:
  37. Index_comment:
  38. *************************** 2. row ***************************
  39. Table: users2
  40. Non_unique: 1
  41. Key_name: pid
  42. Seq_in_index: 1
  43. Column_name: pid
  44. Collation: A
  45. Cardinality: 0
  46. Sub_part: NULL
  47. Packed: NULL
  48. Null: YES
  49. Index_type: BTREE
  50. Comment:
  51. Index_comment:
  52. 2 rows in set (0.00 sec)
  53. ERROR:
  54. No query specified
  55. # 删除唯一约束
  56. mysql> ALTER TABLE users2 DROP INDEXES username;
  57. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘username‘ at line 1
  58. mysql> ALTER TABLE users2 DROP INDEX username;
  59. Query OK, 0 rows affected (0.09 sec)
  60. Records: 0 Duplicates: 0 Warnings: 0
  61. # 查看数据表结构(唯一约束已被删除)
  62. mysql> SHOW COLUMNS FROM users2;
  63. +----------+----------------------+------+-----+---------+-------+
  64. | Field | Type | Null | Key | Default | Extra |
  65. +----------+----------------------+------+-----+---------+-------+
  66. | username | varchar(10) | NO | | NULL | |
  67. | pid | smallint(5) unsigned | YES | MUL | NULL | |
  68. | id | smallint(5) unsigned | NO | | NULL | |
  69. | age | tinyint(3) unsigned | NO | | NULL | |
  70. +----------+----------------------+------+-----+---------+-------+
  71. 4 rows in set (0.00 sec)
  72. </code>

(3)、删除外键约束:

  1. <code class="language-python">ALTER TABLE tbl_name DROP FOREIGN KEY fk_symblo(约束的名字)
  2. </code>

示例:

  1. <code class="language-python"># 要删除外键约束,需要先知道外键约束的名字
  2. # 查看约束名字
  3. mysql> SHOW CREATE TABLE users2;
  4. +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  5. | Table | Create Table |
  6. +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  7. | users2 | CREATE TABLE `users2` (
  8. `username` varchar(10) NOT NULL,
  9. `pid` smallint(5) unsigned DEFAULT NULL,
  10. `id` smallint(5) unsigned NOT NULL,
  11. `age` tinyint(3) unsigned NOT NULL,
  12. KEY `pid` (`pid`),
  13. CONSTRAINT `users2_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`) # 名字为 users2_ibfk_1
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  15. +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  16. 1 row in set (0.00 sec)
  17. # 删除外键约束(pid)
  18. mysql> ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;
  19. Query OK, 0 rows affected (0.01 sec)
  20. Records: 0 Duplicates: 0 Warnings: 0
  21. # 查看约束
  22. mysql> SHOW CREATE TABLE users2;
  23. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  24. | Table | Create Table |
  25. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  26. | users2 | CREATE TABLE `users2` (
  27. `username` varchar(10) NOT NULL,
  28. `pid` smallint(5) unsigned DEFAULT NULL,
  29. `id` smallint(5) unsigned NOT NULL,
  30. `age` tinyint(3) unsigned NOT NULL,
  31. KEY `pid` (`pid`) # 外键约束已被删除,但是 pid 索引还在
  32. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  33. +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  34. 1 row in set (0.00 sec)
  35. # 也可以删除 pid 索引
  36. mysql> ALTER TABLE users2 DROP pid;
  37. Query OK, 0 rows affected (0.07 sec)
  38. Records: 0 Duplicates: 0 Warnings: 0
  39. # 查看约束
  40. mysql> SHOW CREATE TABLE users2;
  41. +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  42. | Table | Create Table |
  43. +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  44. | users2 | CREATE TABLE `users2` (
  45. `username` varchar(10) NOT NULL,
  46. `id` smallint(5) unsigned NOT NULL,
  47. `age` tinyint(3) unsigned NOT NULL
  48. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  49. +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  50. 1 row in set (0.00 sec)
  51. </code>

3.4.6、修改列定义和更改数据表

上面我们了解了如何添加或删除列的约束,或者整个列,其实我们还可以修改列的定义(如列名、列的位置、数据类型等)

(1)、修改列定义:

  1. <code class="language-python">ALTER TABLE tbl_name MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
  2. </code>

调整列的位置:

  1. <code class="language-python"># 将 id 的位置调到首位
  2. # 查看数据表结构,发现 id 在 第二位
  3. mysql> SHOW COLUMNS FROM users2;
  4. +----------+----------------------+------+-----+---------+-------+
  5. | Field | Type | Null | Key | Default | Extra |
  6. +----------+----------------------+------+-----+---------+-------+
  7. | username | varchar(10) | NO | | NULL | |
  8. | id | smallint(5) unsigned | NO | | NULL | |
  9. | age | tinyint(3) unsigned | NO | | NULL | |
  10. +----------+----------------------+------+-----+---------+-------+
  11. 3 rows in set (0.00 sec)
  12. # 将 id 移动至首位(因为我们只是改变位置,数据类型照抄,不改变)
  13. mysql> ALTER TABLE users2 MODIFY id SMALLINT UNSIGNED NOT NULL FIRST; # 不改变数据类型
  14. Query OK, 0 rows affected (0.08 sec)
  15. Records: 0 Duplicates: 0 Warnings: 0
  16. # 查看数据表结构
  17. mysql> SHOW COLUMNS FROM users2;
  18. +----------+----------------------+------+-----+---------+-------+
  19. | Field | Type | Null | Key | Default | Extra |
  20. +----------+----------------------+------+-----+---------+-------+
  21. | id | smallint(5) unsigned | NO | | NULL | |
  22. | username | varchar(10) | NO | | NULL | |
  23. | age | tinyint(3) unsigned | NO | | NULL | |
  24. +----------+----------------------+------+-----+---------+-------+
  25. 3 rows in set (0.00 sec)
  26. </code>

也可以修改列的数据结构,但是要注意的是“从大的数据结构修改到小的,可能会导致数据的丢失”

  1. <code class="language-python"># 将 id 的数据结构修改为 TINYINT
  2. ALTER TABLE users2 MODIFY id TINYINT UNSIGNED NOT NULL ;
  3. </code>

(2)、修改列名称:

  1. <code class="language-python"># 既可以修改列名也可以修改数据结构
  2. ALTER TABLE tbl_name CHANGE [COLUMN] old_name new_clo_name column_definition [FIRST | AFTER col_name]
  3. </code>

示例:

  1. <code class="language-python"># 将 age 列名修改为 user_age,并将其数据类型修改为 SMALLINT
  2. # 查看数据表结构
  3. mysql> SHOW COLUMNS FROM users2;
  4. +----------+----------------------+------+-----+---------+-------+
  5. | Field | Type | Null | Key | Default | Extra |
  6. +----------+----------------------+------+-----+---------+-------+
  7. | id | smallint(5) unsigned | NO | | NULL | |
  8. | username | varchar(10) | NO | | NULL | |
  9. | age | tinyint(3) unsigned | NO | | NULL | |
  10. +----------+----------------------+------+-----+---------+-------+
  11. 3 rows in set (0.00 sec)
  12. # 修改列名和数据结构
  13. mysql> ALTER TABLE users2 CHANGE age user_age SMALLINT UNSIGNED NOT NULL;
  14. Query OK, 0 rows affected (0.10 sec)
  15. Records: 0 Duplicates: 0 Warnings: 0
  16. # 查看数据表结构
  17. mysql> SHOW COLUMNS FROM users2;
  18. +----------+----------------------+------+-----+---------+-------+
  19. | Field | Type | Null | Key | Default | Extra |
  20. +----------+----------------------+------+-----+---------+-------+
  21. | id | smallint(5) unsigned | NO | | NULL | |
  22. | username | varchar(10) | NO | | NULL | |
  23. | user_age | smallint(5) unsigned | NO | | NULL | |
  24. +----------+----------------------+------+-----+---------+-------+
  25. 3 rows in set (0.00 sec)
  26. </code>

(3)、修改数据表名称:

  1. <code class="language-python"># 方法1
  2. ALTER TABLE tbl_name RENAME [TO|AS] new_tbl_name
  3. # 方法2
  4. # 一般情况不建议更改数据表和数据库名称,如果中间有引用了数据库或数据表名字,修改了名字可能导致存储错误
  5. RENAME TABLE tbl_name TO new_tbl_name [, tbl_name2 TO new_tbl_name2]...
  6. </code>

方法一示例:

  1. <code class="language-python"># 将 users2 修改为 users3
  2. mysql> ALTER TABLE users2 RENAME users3;
  3. Query OK, 0 rows affected (0.03 sec)
  4. # 查看当前数据库下数据表
  5. mysql> SHOW TABLES;
  6. +----------------+
  7. | Tables_in_test |
  8. +----------------+
  9. | province |
  10. | tb1 |
  11. | tb2 |
  12. | tb3 |
  13. | tb4 |
  14. | tb5 |
  15. | tb6 |
  16. | users |
  17. | users1 |
  18. | users3 |
  19. +----------------+
  20. 10 rows in set (0.00 sec)
  21. </code>

方法二示例:

  1. <code class="language-python"># 将 users3 修改为 users2
  2. mysql> RENAME TABLE users3 TO users2;
  3. Query OK, 0 rows affected (0.01 sec)
  4. # 查看当前数据库下的数据表
  5. mysql> SHOW TABLES;
  6. +----------------+
  7. | Tables_in_test |
  8. +----------------+
  9. | province |
  10. | tb1 |
  11. | tb2 |
  12. | tb3 |
  13. | tb4 |
  14. | tb5 |
  15. | tb6 |
  16. | users |
  17. | users1 |
  18. | users2 |
  19. +----------------+
  20. 10 rows in set (0.00 sec)
  21. </code>

3.5、小结

技术图片

MySQL 约束及修改数据表(三)

标签:cat   设置   打开   用户   更改   dex   ati   成功   def   

人气教程排行