本文详细记录如何通过命令的方式修改MySQL的表结构,例如新增列、删除列等;不止学会了,你还学懂了,收藏吃灰~

  • 开始之前

    上一篇文章创建了一些表,ER图如下。本文针对score表进行操作,场景就是新增一个备注remarks字段,数据类型为varchar,长度1000,允许为null,默认值为

    测试表er图

查看表结构

查看MySQL数据库中特定表的详细设计信息,可以使用DESCRIBE命令,该命令可以显示出表中所有列的名称、数据类型、默认值、空值约束、键约束等信息。例如:

  • 查看score表的结构
mysql> describe score;
+------------+--------+------+-----+---------+----------------+
| Field      | Type   | Null | Key | Default | Extra          |
+------------+--------+------+-----+---------+----------------+
| id         | int    | NO   | PRI | NULL    | auto_increment |
| student_id | int    | NO   | MUL | NULL    |                |
| course_id  | int    | NO   | MUL | NULL    |                |
| score      | double | NO   |     | NULL    |                |
+------------+--------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

输入命令describe score;便能显示出score表的所有字段,以及每个字段对应的名称、数据类型、默认值、空值约束、键约束等信息;

这里 Key为MUL主要是因为这两个字段有外键约束,约束其与另一个表的对应字段要对应;

  • 查看某个表的某一列的结构
mysql> describe score id;
+-------+------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra          |
+-------+------+------+-----+---------+----------------+
| id    | int  | NO   | PRI | NULL    | auto_increment |
+-------+------+------+-----+---------+----------------+
1 row in set (0.00 sec)

输入describe score id;即可查看score表的id列的结构信息;用法就是describe 表名 列名;

这里也可以使用show columns的方式来查看结构

查看某个表结构:SHOW COLUMNS FROM table_name;

查看某个表某个字段结构:SHOW COLUMNS FROM table_name LIKE 'column_name';

增加列

接上文的场景,给score表新增一个备注remarks字段,数据类型为varchar,长度1000,允许为null,默认值为

mysql> ALTER TABLE score ADD remarks VARCHAR(1000) NULL DEFAULT '无';
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

上面的命令就完成了数据列的插入;下面查看新增列之后的表结构:

mysql> describe score;
+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| id         | int           | NO   | PRI | NULL    | auto_increment |
| student_id | int           | NO   | MUL | NULL    |                |
| course_id  | int           | NO   | MUL | NULL    |                |
| score      | double        | NO   |     | NULL    |                |
| remarks    | varchar(1000) | YES  |     | 无      |                |
+------------+---------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

如上就完成了我们的场景需求;

其中新增命令中,ALTER TABLE用于修改表结构,score是要修改的表名,ADD remarks表示添加一个名为remarks的列,VARCHAR(1000)表示数据类型为varchar,长度为1000NULL表示该列允许为nullDEFAULT '无'表示默认值为

修改列

这里以修改备注列的值不允许为空,默认值为空备注为场景;

mysql> alter table score modify column remarks varchar(1000) not null default '无备注';
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

使用alter table score modify column remarks varchar(1000) not null default '无备注';即可以完成我们的需求,改变后的结构:

mysql> describe score;
+------------+---------------+------+-----+-----------+----------------+
| Field      | Type          | Null | Key | Default   | Extra          |
+------------+---------------+------+-----+-----------+----------------+
| id         | int           | NO   | PRI | NULL      | auto_increment |
| student_id | int           | NO   | MUL | NULL      |                |
| course_id  | int           | NO   | MUL | NULL      |                |
| score      | double        | NO   |     | NULL      |                |
| remarks    | varchar(1000) | NO   |     | 无备注    |                |
+------------+---------------+------+-----+-----------+----------------+
5 rows in set (0.00 sec)

命令格式:ALTER TABLE table_name MODIFY COLUMN column_name column_type NOT NULL DEFAULT '默认值';

table_name表示需要修改的表名,column_name表示需要修改的列名,column_type表示该列原有的数据类型,NOT NULL表示设置该列为非空约束,DEFAULT '默认值'表示设置该列的默认值为默认值

注意column_type是必须的。在SQL中,修改表中某一列的数据类型是一个重要的操作,因为数据类型决定了该列可以存储的数据种类和范围。如果不指定数据类型,MySQL无法解析该语句,就会出现错误:

mysql> alter table score modify column remarks not null default '无备注';
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 'not null default '无备注'' at line 1

重命名列

这里将remarks重命名为new_remarks;

mysql> alter table score rename column remarks TO new_remarks;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

效果:

mysql> describe score;
+-------------+---------------+------+-----+-----------+----------------+
| Field       | Type          | Null | Key | Default   | Extra          |
+-------------+---------------+------+-----+-----------+----------------+
| id          | int           | NO   | PRI | NULL      | auto_increment |
| student_id  | int           | NO   | MUL | NULL      |                |
| course_id   | int           | NO   | MUL | NULL      |                |
| score       | double        | NO   |     | NULL      |                |
| new_remarks | varchar(1000) | NO   |     | 无备注    |                |
+-------------+---------------+------+-----+-----------+----------------+
5 rows in set (0.01 sec)

命令用法:ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name;

table_name表示需要操作的表名,old_column_name是需要被重命名的列名,new_column_name是新的列名,关键字是RENAME

更改列的位置

这个场景很简单,就是改变备注列的位置,但是由于SQL语法的原因,需要区别一下的是,移到某列后面或移到表开始列命令是不一样的;

mysql> ALTER TABLE score MODIFY COLUMN new_remarks varchar(1000) AFTER student_id;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

这是移动到某列之后的命令,效果如下:

mysql> describe score;
+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| id          | int           | NO   | PRI | NULL    | auto_increment |
| student_id  | int           | NO   | MUL | NULL    |                |
| new_remarks | varchar(1000) | YES  |     | NULL    |                |
| course_id   | int           | NO   | MUL | NULL    |                |
| score       | double        | NO   |     | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

下面是移动到表头的命令:

mysql> alter table score modify column new_remarks varchar(1000) first;
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

移动之后的效果:

mysql> describe score;
+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| new_remarks | varchar(1000) | YES  |     | NULL    |                |
| id          | int           | NO   | PRI | NULL    | auto_increment |
| student_id  | int           | NO   | MUL | NULL    |                |
| course_id   | int           | NO   | MUL | NULL    |                |
| score       | double        | NO   |     | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
  • 移动到某列后的命令:ALTER TABLE table_name MODIFY COLUMN column_name column_definition AFTER other_column_name;

    table_name表示需要操作的表名,column_name表示需要被更改位置的列名,column_definition表示列定义,可以包括数据类型、默认值等信息,AFTER关键字后面是该列需要被放置在哪个列的后面,other_column_name是其他列的列名。

  • 移到最开始:ALTER TABLE table_name MODIFY COLUMN column_name column_definition FIRST;

    table_name 是需要操作的表名,column_name 是需要移动的列名,column_definition 是该列的定义,FIRST 表示该列将被移动到表格的最开头位置。

注意

  1. 在使用 ALTER TABLE 命令修改列时,如果省略了数据类型,会报错,因为必须指定新的数据类型。也就是上面的命令不能省略varchar(1000)字段;
  2. 在 MySQL 中,LAST 并不是一个合法的关键字,会导致语法错误。要将列移动到表的最后位置,可以使用 AFTER 关键字指定该列所要移动到的列的名字。也就是:alter table score modify column new_remarks varchar(1000) LAST;是错误的语句!

删除列

这里我们将新建的备注字段删除掉:

mysql> alter table score drop column new_remarks;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

删除后就恢复了最初的效果:

mysql> describe score;
+------------+--------+------+-----+---------+----------------+
| Field      | Type   | Null | Key | Default | Extra          |
+------------+--------+------+-----+---------+----------------+
| id         | int    | NO   | PRI | NULL    | auto_increment |
| student_id | int    | NO   | MUL | NULL    |                |
| course_id  | int    | NO   | MUL | NULL    |                |
| score      | double | NO   |     | NULL    |                |
+------------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

我们使用了 DROP COLUMN 子句来指示删除该列。请注意,这会永久性地从表中删除该列!

Q&A

表结构中的Extra是什么意思

MySQL表结构中的Extra字段是用于显示额外的信息和注释,该字段提供了一些重要的信息,例如自增、默认值、主键信息等。它可以告诉用户更多关于该列的信息,帮助用户更好地理解该列的作用和用途。

常见的Extra字段的取值包括:

  • auto_increment:表示该列是自增主键。
  • on update CURRENT_TIMESTAMP:表示该列设置了自动更新时间戳功能。
  • DEFAULT ‘xxx’:表示该列设置了默认值为xxx。

表结构的key代表什么

  • PRI:表示该列是主键,主键是一种特殊的索引,用于唯一标识表中的每一行数据。每个表最多只能有一个主键,主键限制表中的数据不能重复,并且不能为NULL。
  • MUL:非唯一索引,该索引包括多个重复的键值时,Key属性值就会显示为mul
  • UNI: 表示该列是唯一键。唯一键也可以用于唯一标识表中的每一行数据,但是它允许NULL值。一个表可以有多个唯一键。
  • FULLTEXT: 表示该列是全文索引。全文索引用于优化全文搜索,例如对文章标题和正文进行关键字搜索。一个表最多只能有一个全文索引。
  • ``(空): 表示该列既不是主键,也不是唯一键。

例如,当使用DESCRIBE命令查看一个名为students的表时,可能会得到以下输出:

mysql> DESCRIBE students;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int(11)     | NO   | PRI | NULL    |       |
| name     | varchar(50) | YES  |     | NULL    |       |
| gender   | char(1)     | YES  |     | NULL    |       |
| age      | int(11)     | YES  |     | NULL    |       |
| email    | varchar(80) | YES  | UNI | NULL    |       |
| address  | varchar(100)| YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

其中,id列的KeyPRI,表示它是主键;email列的KeyUNI,表示它是唯一键;其他列的Key""(空),表示它们既不是主键,也不是唯一键。

什么是索引

MySQL索引是一种帮助MySQL快速获取数据的数据结构,就像是书的目录一样可以快速访问特定信息。它可以提高数据库查询的速度,基本原理是使用空间换取时间,将索引存储在磁盘上的文件中以加快读写速度。使用索引可以对表中的一列或多列的值进行排序,从而快速访问表中的特定信息。索引的实现依赖于数据库的存储引擎和数据检索引擎的设计,因此选用合适的数据结构能够提高数据检索性能,并且对于大规模数据存储的数据库而言,选择合适的高效查找算法是非常重要的。

  • 主键索引:索引列中的值必须是唯一的,不允许有空值。
  • 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值。
  • 唯一索引:索引列中的值必须是唯一的,但是允许为空值。
  • 全文索引:只能在文本类型CHAR,VARCHAR,TEXT类型字段上创建全文索引。字段长度比较大时,如果创建普通索引,在进行like模糊查询时效率比较低,这时可以创建全文索引。 MyISAM和InnoDB中都可以使用全文索引。
  • 空间索引:MySQL在5.7之后的版本支持了空间索引,而且支持OpenGIS几何数据模型。MySQL在空间索引这方面遵循OpenGIS几何数据模型规则。
  • 前缀索引:在文本类型如CHAR,VARCHAR,TEXT类列上创建索引时,可以指定索引列的长度,但是数值类型不能指定。
  • 其他(按照索引列数量分类)
    • 单列索引
    • 组合索引:组合索引的使用,需要遵循最左前缀匹配原则(最左匹配原则)。一般情况下在条件允许的情况下使用组合索引替代多个单列索引使用。

如何查看某个表中的索引

SHOW INDEX FROM score;

image-20230414164537667

下面是这些字段的解释:

  1. Table:索引所在的表名。
  2. Non_unique:该索引是否允许出现重复值,0表示唯一索引,1表示允许重复值。
  3. Key_name:索引的名称。
  4. Seq_in_index:索引中该列的顺序,从1开始。
  5. Column_name:索引中包含的列名。
  6. Collation:对该列使用的字符集排序规则,如果该列不在任何索引中,则为NULL。
  7. Cardinality:索引中唯一值的数量估计,不一定准确。
  8. Sub_part:如果是前缀索引,则表示被索引字符串的长度,否则为NULL。
  9. Packed:如果是PACK_KEYS索引类型,则表示使用的压缩率,否则为NULL。
  10. Null:该列是否允许NULL值,如果允许,则为YES,否则为NO。
  11. Index_type:索引类型,例如Btree、Hash等。
  12. Comment:索引的注释。
  13. Index_comment:索引注释的字符集和排序规则。
  14. Visible:该索引是否可见,0表示隐藏,1表示可见。
  15. Expression:如果该索引是函数或表达式的结果,则为表达式或函数名,否则为NULL。

如何查看某个表的约束

mysql> SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE
    -> FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    -> WHERE TABLE_SCHEMA = 'student_score_db' and table_name='score';
+------------------+-----------------+
| CONSTRAINT_NAME  | CONSTRAINT_TYPE |
+------------------+-----------------+
| PRIMARY          | PRIMARY KEY     |
| fk_score_course  | FOREIGN KEY     |
| fk_score_student | FOREIGN KEY     |
+------------------+-----------------+
3 rows in set (0.00 sec)

上述SQL语句将会返回给定表的所有约束名称和类型,例如PRIMARY KEY、FOREIGN KEY、UNIQUE等。如果要查看特定约束的详细信息(例如包含的列),可以使用INFORMATION_SCHEMA.KEY_COLUMN_USAGE表进行查询。


欢 迎 关 注 博 主 个 人 小 程 序!