Skip to content

数据库的基本操作

创建数据库

MySQL 安装完成之后,将会在其 data 目录下自动创建几个必需的数据库,可以使用 SHOW DATABASES; 语句来查看当前所有存在的数据库,输入语句如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| blog_service       |
| happylife          |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.07 sec)

可以看到,数据库列表中包含了 6 个数据库,MySQL 是必需的,它描述用户访问权限,

创建数据库是在系统磁盘上划分一块区域用于数据的存储和管理,如果管理员在设置权限的时候为用户创建了数据库,则可以直接使用,否则需要自己创建数据库。
MySQL 中创建数据库的基本 SQL 语法格式为:

1
CREATE DATABASE database_name;

database_name 为要创建的数据库名称,该名称不能与已经存在的数据库重名

1
CREATE DATABASE test_db;

数据库创建好之后,可以使用 SHOW CREATE DATABASE 声明查看数据库的定义

1
2
3
4
5
6
7
mysql> SHOW CREATE DATABASE test_db;
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                                   |
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
| test_db  | CREATE DATABASE `test_db` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

可以看到,如果数据库创建成功,就将显示数据库的创建信息

再次使用 SHOW DATABASES; 语句来查看当前所有存在的数据库,命令如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| blog_service       |
| happylife          |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_db            |
+--------------------+
7 rows in set (0.00 sec)

可以看到,数据库列表中包含了刚刚创建的数据库 test_db 和其他已经存在的数据库的名称

删除数据库

删除数据库是将已经存在的数据库从磁盘空间上清除,清除之后,数据库中的所有数据也将一同被删除。
删除数据库语句和创建数据库的命令相似,MySQL 中删除数据库的基本语法格式为:

1
DROP DATABASE database_name;
1
2
3
4
5
mysql> DROP DATABASE test_db;
Query OK, 0 rows affected (0.10 sec)

mysql> SHOW CREATE DATABASE test_db;
ERROR 1049 (42000): Unknown database 'test_db'

创建数据表

所谓创建数据表,指的是在已经创建好的数据库中建立新表。
创建数据表的过程是规定数据列的属性的过程,同时也是实施数据完整性(包括实体完整性、引用完整性和域完整性等)约束的过程

创建表的语法形式

数据表属于数据库,在创建数据表之前,应该使用语句 USE <数据库名> 指定操作是在哪个数据库中进行,如果没有选择数据库,就会抛出 No database selected 的错误

创建数据表的语句为 CREATE TABLE,语法规则如下:

1
2
3
4
5
6
7
CREATE TABLE <表名>
{
    字段名1, 数据类型 [列级别约束条件] [默认值],
    字段名2, 数据类型 [列级别约束条件] [默认值],
    ......
    [表级别约束条件]
};

使用 CREATE TABLE 创建表时,必须指定以下信息:

(1) 要创建的表的名称,不区分大小写,不能使用 SQL 语言中的关键字,如 DROP、ALTER、INSERT 等
(2) 数据表中每一列(字段)的名称和数据类型,如果创建多列,就要用逗号隔开。

例: 创建员工表 tb_emp1,结构如表所示

字段名称 数据类型 备注
id INT(11) 员工编号
name VARCHAR(25) 员工名称
deptId INT(11) 所在部门编号
salary FLOAT 工资

创建数据库:

1
2
mysql> CREATE DATABASE test_db;
Query OK, 1 row affected (0.25 sec)

选择创建的数据库

1
2
mysql> USE test_db;
Database changed

创建 tb_emp1 表:

1
2
3
4
5
6
7
8
mysql> CREATE TABLE tb_emp1
    -> (
    ->     id  INT(11),
    ->     name  VARCHAR(25),
    ->     deptId  INT(11),
    ->     salary  FLOAT
    -> );
Query OK, 0 rows affected, 2 warnings (0.08 sec)

语句执行后,便创建了一个名称为 tb_emp1 的数据表,使用 SHOW TABLES; 语句查看数据表是否创建成功,SQL 语句如下:

1
2
3
4
5
6
7
mysql> SHOW TABLES;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_emp1           |
+-------------------+
1 row in set (0.00 sec)

使用主键约束

主键,又称主码,是表中一列多多列的组合。
主键约束(Primary Key Constraint)要求主键列的数据唯一,并且不允许为空。
主键能够唯一地标识表中的一条记录,可以结合外键来定义不同数据表之间的关系,并且可以加快数据库查询的速度。
主键和记录之间的关系如同身份证和人之间的关系,它们之间是一一对应的。
主键分为两种类型: 单字段主键和多字段联合主键。

单字段主键

主键由一个字段组成,SQL 语句格式分为以下两种情况:

(1) 在定义列的同时指定主键,语法规则如下:

1
字段名 数据类型 PRIMARY KEY [默认值]

例: 定义数据表 tb_emp2,其主键为 id,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_emp2
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25),
    deptId  INT(11),
    salary  FLOAT
);

(2) 在定义完所有列之后指定主键

1
[CONSTRAINT <约束名>] PRIMARY KEY [字段名]

例: 定义数据表 tb_emp3,其主键为 id,SQL 语句如下:

1
2
3
4
5
6
7
8
CREATE TABLE tb_emp3
(
    id  INT(11),
    name  VARCHAR(25),
    deptId  INT(11),
    salary  FLOAT,
    PRIMARY KEY(id)
);

上述两个例子执行后的结果是一样的,都会在 id 字段上设置主键约束

多字段联合主键

主键由多个字段联合组成,语法规则如下:

1
PRIMARY KEY [字段1, 字段2, ..., 字段n]

例: 定义数据表 tb_emp4,假设表中间没有主键 id,为了唯一确定一个员工,可以把 name、deptId 联合起来作为主键,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_emp4
(
    name  VARCHAR(25),
    deptId  INT(11),
    salary FLOAT,
    PRIMARY KEY(name,deptId)
);

语句执行后,便创建了一个名称为 tb_emp4 的数据表,name 字段和 deptId 字段组合在一起成为 tb_emp4 的多字段联合主键

使用外键约束

外键用来在两个表的数据之间建立连接,可以是一列或者多列。
一个表可以有一个或多个外键。外键对应的是参照完整性,一个表的外键可以为空值,若不是空值,则每一个外键值必须等于另一个表中主键的某个值。

外键: 首先它是表中的一个字段,虽可以不是本表的主键,但要对应另外一个表的主键。
外键的主要作用是保证数据引用的完整性,定义外键后,不允许删除在另一个表中具有关联关系的行。
外键的作用是保持数据的一致性、完整性。
例如,部门表 tb_dept 的主键是 id,在员工表 tb_emp5 中有一个键 deptId 与这个 id 关联

主表(父表): 对于两个具有关联关系的表而言,相关联字段中主键所在的那个表即是主表。

从表(子表): 对于两个具有关联关系的表而言,相关联字段中外键所在的那个表即是从表。

创建外键的语法规则如下:

1
[CONSTRAINT <外键名>] FOREIGN KEY 字段名1 [,字段名2,...] REFERENCES <主表名> 主键列1[,主键例如2,...]

"外键名" 为定义的外键约束的名称,一个表中不能有相同名称的外键;
"字段名" 表示子表需要添加外键约束的字段列;
"主表名" 即被子表外键所依赖的表的名称;
"主键列" 表示主表中定义的主键列,或者列组合。

例: 定义数据表 tb_emp5,并在 tb_emp5 表上创建外键约束

字段名称 数据类型 备注
id INT(11) 部门编号
name VARCHAR(22) 部门名称
location VARCHAR(50) 部门位置

创建一个部门表 tb_dept1,表结构如上表所示,SQL 语句如下:

1
2
3
4
5
6
CREATE TABLE tb_dept1
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(22) NOT NULL,
    location VARCHAR(50)
);

定义数据表 tb_emp5,让它的键 deptId 作为外键关联到 tb_dept1 的主键 id,SQL 语句为:

1
2
3
4
5
6
7
8
CREATE TABLE tb_emp5
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25),
    deptId  INT(11),
    salary FLOAT,
    CONSTRAINT fk_emp_dept1 FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
);

以上语句执行成功之后,在表 tb_emp5 上添加了名称为 fk_emp_dept1 的外键约束,外键名称为 deptId,其依赖于表 tb_dept1 的主键 id

使用非空约束

非空约束(Not Null Constraint)指字段的值不能为空。
对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统会报错。

非空约束的语法规则如下:

1
字段名 数据类型 not null

例: 定义数据表 tb_emp6,指定员工的名称不能为空,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_emp6
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25) NOT NULL,
    deptId  INT(11),
    salary  FLOAT
);

执行后,在 tb_emp6 中创建了一个 name 字段,其插入值不能为空(NOT NULL)

使用唯一性约束

唯一性约束(Unique Constraint)要求该列唯一,允许为空,但只能出现一个空值。
唯一约束可以确保一列或者几列不出现重复值。

唯一性约束的语法规则如下:

(1) 在定义完列之后直接指定唯一约束,语法规则如下:

1
字段名 数据类型 UNIQUE

例: 定义数据表 tb_dept2,指定部门的名称唯一,SQL 语句如下:

1
2
3
4
5
6
CREATE TABLE tb_dept2
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(22) UNIQUE,
    location  VARCHAR(50)
);

(2) 在定义完所有列之后指定唯一约束,语法规则如下:

1
[CONSTRAINT <约束名>] UNIQUE(<字段名>)

例: 定义数据表 tb_dept3,指定部门的名称唯一,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_dept3
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(22),
    location VARCHAR(50),
    CONSTRAINT STH UNIQUE(name)
);

UNIQUE 和 PRIMARY KEY 的区别: 一个表中可以有多个字段声明为 UNIQUE,但只能有一个 PRIMARY KEY 声明;
声明为 PRIMARY KEY 的列不允许有空值,但是声明为 UNIQUE 的字段允许空值(NULL) 的存在

使用默认约束

默认约束(Default Constraint)指定某列的默认值。
如果男性同学较多,性别就可以默认为 '男'。
如果插入一条新的记录时没有为这个字段赋值,那么系统会自动为这个字段赋值为 '男'。

默认约束的语法规则如下:

1
字段名 数据类型 DEFAULT 默认值

例: 定义数据表 tb_emp7,指定员工的部门编号默认为 1111,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_emp7
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25) NOT NULL,
    deptId  INT(11) DEFAULT 1111,
    salary FLOAT
);

以上语句执行成功之后,表 tb_emp7 上的字段 deptId 拥有了一个默认的值 1111,新插入的记录如果没有指定部门编号,则默认都为 1111

设置表的属性值自动增加

在数据库应用中,经常希望在每次插入新记录时,系统自动生成字段的主键值。
可以通过为表主键添加 AUTO_INCREMENT 关键字来实现。
默认的,在 MySQL 中 AUTO_INCREMENT 的初始值是 1,每新增一条记录,字段值自动加 1.
一个表只能有一个字段使用 AUTO_INCREMENT 约束,且该字段必须为主键的一部分。
AUTO_INCREMENT 约束的字段可以是任何整数类型(TINYINT、SMALLINT、INT、BIGINT 等)。

设置表的属性值自动增加的语法规则如下:

1
字段名 数据类型 AUTO_INCREMENT

例: 定义数据表 tb_emp8,指定员工的编号自动递增,SQL 语句如下:

1
2
3
4
5
6
7
CREATE TABLE tb_emp8
(
    id  INT(11) PRIMARY KEY AUTO_INCREMENT,
    name  VARCHAR(25) NOT NULL,
    deptId INT(11),
    salary  FLOAT
);

上述例子执行后,会创建名称为 tb_emp8 的数据表。
表 tb_emp8 中的 id 字段的值在添加记录的时候会自动增加,在插入记录的时候,默认的自增字段 id 的值从 1 开始,每次添加一条新纪录,该值自动加 1.

例如,执行乳腺癌插入语句:

1
INSERT INTO tb_emp8(name,salary) VALUES('Lucy',1000),('Lura',1200),('Kevin',150);

提示:
这里使用 INSERT 声明向表中插入记录的方法,并不是 SQL 的标准语法,这种语法不一定被其他的数据库支持,只能在 MySQL 中使用

语句执行完后,tb_tmp8 表中增加 3 条记录,在这里并没有输入 id 的值,但系统已经自动添加该值,使用 SELECT 命令查看记录,如下所示:

1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM tb_emp8;
+----+-------+--------+--------+
| id | name  | deptId | salary |
+----+-------+--------+--------+
|  1 | Lucy  |   NULL |   1000 |
|  2 | Lura  |   NULL |   1200 |
|  3 | Kevin |   NULL |    150 |
+----+-------+--------+--------+
3 rows in set (0.00 sec)

查看数据表结构

使用 SQL 语句创建好数据表之后,可以查看表结构的定义,以确认表的定义是否正确。
在 MySQL 中,查看表结构可以使用 DESCRIBESHOW CREATE TABLE 语句。

查看表基本结构语句 DESCRIBE

DESCRIBE/DESC 语句可以查看表的字段信息,其中包括字段名、字段数据类型、是否为主键、是否有默认值等。
语法规则如下:

1
DESCRIBE 表名;

或者简写为:

1
DESC 表名;

例: 分别使用 DESCRIBE 和 DESC 查看表 tb_dept1 和 表 tb_emp1 的表结构

查看 tb_dept1 表结构,SQL 语句如下:

1
2
3
4
5
6
7
8
9
mysql> DESCRIBE tb_dept1;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int         | NO   | PRI | NULL    |       |
| name     | varchar(22) | NO   |     | NULL    |       |
| location | varchar(50) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

查看 tb_emp1 表结构,SQL 语句如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> DESC tb_emp1;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int         | YES  |     | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| deptId | int         | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> DESC tb_emp7;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int         | NO   | PRI | NULL    |       |
| name   | varchar(25) | NO   |     | NULL    |       |
| deptId | int         | YES  |     | 1111    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> DESC tb_emp8;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int         | NO   | PRI | NULL    | auto_increment |
| name   | varchar(25) | NO   |     | NULL    |                |
| deptId | int         | YES  |     | NULL    |                |
| salary | float       | YES  |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

其中,各个字段的含义分别解释如下:

  • NULL: 考试该列是否可以存储 NULL 值
  • key: 表示该列是否已编制索引。PRI 表示该列是表主键的一部分;UNI 表示该列是 UNIQUE 索引的一部分;MUL 表示在列中某个给定值允许出现多次。
  • Default: 表示该列是否有默认值,有的话指定值是多少
  • Extra: 表示可以获取的与给定列有关附加信息,例如 AUTO_INCREMENT 等。

查看表详细结构

SHOW CREATE TABLE 语句可以用来显示创建表时的 CREATE TABLE 语句,语法格式如下:

1
SHOW CREATE tABLE <表名\G>

提示:
使用 SHOW CREATE TABLE 语句,不仅可以查看表创建时候的详细语句,还可以查看存储引擎和字符编码。

如果不加 '\G' 参数,显示的结果可能非常混乱,加上参数 '\G' 之后,可使显示结果更加直观,易于查看。

例: 使用 SHOW CREATE TABLE 查看表 tb_emp1 的详细信息,SQL 语句如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> SHOW CREATE TABLE tb_emp1;
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                       |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb_emp1 | CREATE TABLE `tb_emp1` (
  `id` int DEFAULT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

使用 '\G' 之后的结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> SHOW CREATE TABLE tb_emp1\G
*************************** 1. row ***************************
       Table: tb_emp1
Create Table: CREATE TABLE `tb_emp1` (
  `id` int DEFAULT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

修改数据表

修改表指的是修改数据库中已经存在的数据表的结构。MySQL 使用 ALTER TABLE 语句修改表。
常用的修改表的操作有修改表名、修改字段数据类型或字段名、增加和删除字段,修改字段的排列位置、更改表的存储引擎、删除表的外键约束等。

修改表名

MySQL 是通过 ALTER TABLE 语句来实现表名的修改的,具体的语法规则如下:

1
ALTER TABLE <旧表名> RENAME [TO] <新表名>;

其中,TO 为可选参数,使用与否均不影响结果。

例: 将数据表 tb_dept3 改名为 tb_deptment3

执行修改表名操作之前,使用 SHOW TABLEs 查看数据库中所有的表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
mysql> SHOW TABLES;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_dept1          |
| tb_dept2          |
| tb_dept3          |
| tb_emp1           |
| tb_emp2           |
| tb_emp3           |
| tb_emp4           |
| tb_emp5           |
| tb_emp6           |
| tb_emp7           |
| tb_emp8           |
+-------------------+
11 rows in set (0.00 sec)

使用 ALTER TABLE 将表 tb_dept3 改名为 tb_deptment3,SQL 语句如下:

1
ALTER TABLE tb_dept3 RENAME tb_deptment3;

语句执行后,检查表 tb_dept3 是否改名成功:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
mysql> SHOW TABLES;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_dept1          |
| tb_dept2          |
| tb_deptment3      |
| tb_emp1           |
| tb_emp2           |
| tb_emp3           |
| tb_emp4           |
| tb_emp5           |
| tb_emp6           |
| tb_emp7           |
| tb_emp8           |
+-------------------+
11 rows in set (0.00 sec)

修改字段的数据将类型

修改字段的数据类型,就是把字段的数据类型转换成另一种数据类型。在 MySQL 中修改字段数据类型的语法规则如下:

1
ALTER TABLE <表名> MODIFY <字段名> <数据类型>

其中,"表名" 指要修改数据类型的字段所在表的名称,"字段名" 指需要修改的字段,"数据类型" 指修改后字段的新数据类型

例: 将数据表 tb_dept1 中 name 字段的数据类型由 VARCHAR(22) 修改成 VARCHAR(30)

执行修改操作之前,使用 DESC 查看 tb_dept1 表结构,结果如下:

1
2
3
4
5
6
7
8
9
mysql> DESC tb_dept1;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int         | NO   | PRI | NULL    |       |
| name     | varchar(22) | NO   |     | NULL    |       |
| location | varchar(50) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

可以看到现在 name 字段的数据类型为 VARCHAR(22),下面修改其类型。输入如下 SQL 语句并执行:

1
ALTER TABLE tb_dept1 MODIFY name VARCHAR(30);

再次使用 DESC 查看表:

1
2
3
4
5
6
7
8
9
mysql> DESC tb_dept1;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int         | NO   | PRI | NULL    |       |
| name     | varchar(30) | YES  |     | NULL    |       |
| location | varchar(50) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

修改字段名

语法规则如下:

1
ALTER TABLE <表名> CHANGE <旧字段名> <新字段名> <新数据类型>;

其中,"旧字段名" 指修改前的字段名; "新字段名" 指修改后的字段名; "新数据类型" 指修改后的数据类型,如果不需要修改字段的数据类型,将新数据类型设置成与原来一样即可,但数据类型不能为空。

例: 将数据表 tb_dept1 中的 location 字段名称改为 loc,数据类型保持不变,SQL 语句如下:

1
ALTER TABLE tb_dept1 CHANGE location loc VARCHAR(50);

使用 DESC 查看表 tb_dept1:

1
2
3
4
5
6
7
8
9
mysql> DESC tb_dept1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(30) | YES  |     | NULL    |       |
| loc   | varchar(50) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

提示:
由于不同类型的数据在机器中存储的方式及长度并不相同,修改数据类型可能会影响到数据表中已有的数据记录,因此当数据库中已经有数据时,不要轻易修改数据类型。

添加字段

随着业务需求的变化,可能需要在已经存在的表中添加新的字段。一个完整字段包括字段名、数据类型、完整性约束。
添加字段的语法格式如下:

1
ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] [FIRST | AFTER 已存在字段名];

"新字段名" 为需要添加的字段的名称; "FIRST" 为可选参数,其作用是将新添加的字段设置为表的第一个字段;
"AFTER" 为可选参数,其作用是将新添加的字段添加到指定的 "已存在字段名" 的后面

提示:
"FIRST" 或 "AFTER 已存在字段名" 用于指定新增字段在表中的位置,如果 SQL 语句中没有这两个参数,则默认将新添加的字段设置为数据表的最后列

添加无完整性约束条件的字段

例: 在数据表 tb_dept1 中添加一个没有完整性约束的 INT 类型的字段 mangaerId(部门经理编号),SQL 语句如下:

1
ALTER TABLE tb_dept1 ADD managerId INT(10);

使用 DESC 查看表 tb_dept1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

添加有完整性约束条件的字段

例: 在数据表 tb_dept1 中添加一个不能为空的 VARCHAR(12) 类型的字段 column1,SQL 语句如下:

1
ALTER TABLE tb_dept1 ADD column1 VARCHAR(12) NOT NULL;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
| column1   | varchar(12) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

在表的第一列添加一个字段

例: 在数据表 tb_dept1 中添加一个 INT(11) 类型的字段 column2,SQL 语句如下:

1
ALTER TABLE tb_dept1 ADD column2 INT(11) FIRST;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| column2   | int         | YES  |     | NULL    |       |
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
| column1   | varchar(12) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

在表的指定列之后添加一个字段

例: 在数据表 tb_dept1 中 name 列后添加一个 INT(11) 类型的字段 column3,SQL 语句如下:

1
ALTER TABLE tb_dept1 ADD column3 INT(11) AFTER name;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| column2   | int         | YES  |     | NULL    |       |
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| column3   | int         | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
| column1   | varchar(12) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

删除字段

删除字段是将数据表中的某个字段从表中移除,语法格式如下:

1
ALTER TABLE <表名> DROP <字段名>;

例: 删除数据表 tb_dept1 表中的 column2 字段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| column2   | int         | YES  |     | NULL    |       |
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| column3   | int         | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
| column1   | varchar(12) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)
1
ALTER TABLE tb_dept1 DROP column2;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| column3   | int         | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
| column1   | varchar(12) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

修改字段的排列位置

对于一个数据表来说,在创建的时候,字段在表中的排列顺序就已经确定了,但表的结构并不是完全不可以改变的,可以通过 ALTER TABLE 来改变表中字段的相对位置。语法格式如下:

1
ALTER TABLE <表名> MODIFY <字段1> <数据类型> FIRST | AFTER <字段2>;

其中,"字段1" 指要修改位置的字段; "数据类型" 指 "字段1" 的数据类型;
"FIRST" 为可选参数,指将 "字段1" 修改为表的第一个字段;
"AFTER 字段2" 指将 "字段1" 插入到 "字段2" 后面

修改字段为表的第一个字段

例: 将数据表 tb_dept1 中的 column1 字段修改为表的第一个字段,SQL 语句如下;

1
ALTER TABLE tb_dept1 MODIFY column1 VARCHAR(12) FIRST;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| column1   | varchar(12) | YES  |     | NULL    |       |
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| column3   | int         | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

修改字段到表的指定列之后

例: 将数据表 tb_dept1 中的 column1 字段插入到 loc 字段后面,SQL 语句如下:

1
ALTER TABLE tb_dept1 MODIFY column1 VARCHAR(12) AFTER loc;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> DESC tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int         | NO   | PRI | NULL    |       |
| name      | varchar(30) | YES  |     | NULL    |       |
| column3   | int         | YES  |     | NULL    |       |
| loc       | varchar(50) | YES  |     | NULL    |       |
| column1   | varchar(12) | YES  |     | NULL    |       |
| managerId | int         | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

更改表的存储引擎

存储引擎是 MySQL 中的数据存储在文件或者内存中时采用的不同技术实现。
可以根据自己的需要,选择不同的引擎,甚至可以为每一张表选择不同的存储引擎。
MySQL 中主要的存储引擎有 MyISAM、InnoDB、MEMORY(HEAP)、BDB、FEDERATED 等。

可以使用 "SHOW ENGINES;" 语句查看系统支持的存储引擎

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.01 sec)

更改表的存储引擎的语法格式如下:

1
ALTER TABLE <表名> ENGINE=<更改后的存储引擎名>;

例: 将数据表 tb_deptment3 的存储引擎修改为 MyISAM。

在修改存储引擎之前,先使用 SHOW CREATE TABLE 查看表 tb_deptment3 当前的存储引擎,结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
mysql> SHOW CREATE TABLE tb_deptment3 \G
*************************** 1. row ***************************
       Table: tb_deptment3
Create Table: CREATE TABLE `tb_deptment3` (
  `id` int NOT NULL,
  `name` varchar(22) DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `STH` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

可以看到,表 tb_deptment3 当前的存储引擎为 ENGINE=InnoDB,接下来修改存储引擎类型,输入如下 SQL 语句并执行

1
ALTER TABLE tb_deptment3 ENGINE=MyISAM;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
mysql> SHOW CREATE TABLE tb_deptment3 \G
*************************** 1. row ***************************
       Table: tb_deptment3
Create Table: CREATE TABLE `tb_deptment3` (
  `id` int NOT NULL,
  `name` varchar(22) DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `STH` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

删除表的外键约束

对于数据库中定义的外键,如果不再需要,可以将其删除。
外键一旦删除,就会解除主表和从表间的关联关系,MySQL 中删除外键的语法格式如下:

1
ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>

"外键约束名" 指在定义表时 CONSTRAINT 关键字后面的参数

例: 删除数据表 tb_emp9 中的外键约束

首先创建表 tb_emp9,创建外键 deptId 关联 tb_dept1 表的主键 id,SQL 语句如下:

1
2
3
4
5
6
7
8
CREATE TABLE tb_emp9
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25),
    deptId  INT(11),
    salary  FLOAT,
    CONSTRAINT fk_emp_dept FOREIGN KEY (deptId) REFERENCES tb_dept1(id)
);

使用 SHOW CREATE TABLE 查看表 tb_emp9 的结构,结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mysql> SHOW CREATE TABLE tb_emp9 \G
*************************** 1. row ***************************
       Table: tb_emp9
Create Table: CREATE TABLE `tb_emp9` (
  `id` int NOT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_emp_dept` (`deptId`),
  CONSTRAINT `fk_emp_dept` FOREIGN KEY (`deptId`) REFERENCES `tb_dept1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

可以看到,已经成功添加了表的外键,下面删除外键约束,SQL 语句如下:

1
ALTER TABLE tb_emp9 DROP FOREIGN KEY fk_emp_dept;

执行完毕之后,将删除表 tb_emp9 的外键约束。
使用 SHOW CREATE TABLE 再次查看表 tb_emp9 结构,结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> SHOW CREATE TABLE tb_emp9 \G
*************************** 1. row ***************************
       Table: tb_emp9
Create Table: CREATE TABLE `tb_emp9` (
  `id` int NOT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_emp_dept` (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

可以看到,tb_emp9 中已经不存在 FOREIGN KEY,原有的名称为 fk_emp_dept 的外键约束删除成功

删除数据表

删除数据表就是将数据库中已经存在的表从数据库中删除。
注意,在删除表的同时,表的定义和表中所有的数据均会被删除。
因此,在进行删除操作前,最好对表中的数据做一个备份,以免造成无法晚会的后果。

删除没有被关联的表

在 MySQL 中,使用 DROP TABLE 可以一次删除一个或多个没有被其他表关联的数据表。
语法格式如下:

1
DROP TABLE [IF EXISTS] 1,2,...,n; 

其中,"表n" 指要删除的表的名称,后面可以同时删除多个表,只需将要删除的表名一次写在后面,相互之间用逗号隔开即可。
如果要删除的数据表不存在,则 MySQL 会提示一条错误信息,"ERROR 1051(42S02): Unknown table '表名'"。
参数 "IF EXISTS" 用于在删除前判断删除的表是否存在,加上该参数后,再删除表的时候,如果表不存在,SQL 语句可以顺利执行,但是会发出警告。

例: 删除数据表 tb_dept2,SQL 语句如下:

1
DROP TABLE IF EXISTS tb_dept2;

删除被其他表关联的主表

在数据表之间存在外键关联的情况下,如果直接删除父表,结果会显示失败,原因是直接删除将破坏表的参照完整性。
如果必须要删除,可以先删除它关联的子表,再删除父表,只是这样就同时删除了两个表中的数据。

有的情况下可能要保留子表,这时要单独删除父表,只需将关联的表的外键约束条件取消,然后就可以删除父表了

在数据库中创建两个关联表,首先创建表 tb_dept2,SQL 语句如下:

1
2
3
4
5
6
CREATE TABLE tb_dept2
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(22),
    location  VARCHAR(50)
);

接下来创建表 tb_emp,SQL 语句如下:

1
2
3
4
5
6
7
8
CREATE TABLE tb_emp
(
    id  INT(11) PRIMARY KEY,
    name  VARCHAR(25),
    deptId  INT(11),
    salary  FLOAT,
    CONSTRAINT fk_emp_dept FOREIGN KEY (deptId) REFERENCES tb_dept2(id)
);

使用 SHOW CREATE TABLE 命令查看表 tb_emp 的外键约束,结果如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mysql> SHOW CREATE TABLE tb_emp\G
*************************** 1. row ***************************
       Table: tb_emp
Create Table: CREATE TABLE `tb_emp` (
  `id` int NOT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_emp_dept` (`deptId`),
  CONSTRAINT `fk_emp_dept` FOREIGN KEY (`deptId`) REFERENCES `tb_dept2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

例: 删除被数据表 tb_emp 关联的数据表 tb_dept2。

首先试着直接删除父表 tb_dept2,输出如下删除语句

1
2
mysql> DROP TABLE tb_dept2;
ERROR 3730 (HY000): Cannot drop table 'tb_dept2' referenced by a foreign key constraint 'fk_emp_dept' on table 'tb_emp'.

如前所述,在存在外键约束时,主表不能被直接删除。

接下来,解除关联子表 tb_emp 的外键约束,SQL 语句如下:

1
ALTER TABLE tb_emp DROP FOREIGN KEY fk_emp_dept;

语句成功执行后,将取消表 tb_emp 和表 tb_dept2 之间的关联关系,此时,可以输入删除语句,将原来的父表 tb_dept2 删除,SQL 语句如下:

1
DROP TABLE tb_dept2;

8.0 新特性1

在 MySQL 8.0 版本之前,默认字符集为 latin1,utf8 字符集指向的是 utf8mb3。
网站开发人员在数据库设计的时候往往会将编码修改为 utf8 字符集。如果遗忘修改默认的编码,就会出现乱码的问题。
从 MySQL 8.0 开始,数据库的默认编码改为 utf8mb4,从而避免了上述的乱码问题。

1
2
3
4
5
6
7
mysql> SHOW VARIABLES LIKE 'character_set_database';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| character_set_database | utf8mb4 |
+------------------------+---------+
1 row in set (0.07 sec)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysql> SHOW CREATE TABLE tb_emp\G
*************************** 1. row ***************************
       Table: tb_emp
Create Table: CREATE TABLE `tb_emp` (
  `id` int NOT NULL,
  `name` varchar(25) DEFAULT NULL,
  `deptId` int DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_emp_dept` (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

专家解惑

疑问1: 表删除操作须谨慎

表删除操作将把表的定义和表中的数据一起删除,并且 MySQL 在执行删除操作时,不会有任何的确认信息提示,因此执行删除操作时应当慎重。
在删除表前,最好对表中的数据进行备份,这样当操作失误时可以对数据进行恢复,以免造成无法挽回的后果。

同样的,在使用 ALTER TABLE 进行表的基本修改操作时,在执行操作过程之前,也应该确保对数据进行完整的备份,因为数据库的改变时无法撤销的,如果添加了一个不需要的字段,可以将其删除;
相同的,如果删除了一个需要的列,该列下面的所有数据都将会丢失。

疑问2: 每一个表中都要有一个主键吗?

并不是每一个表中都需要主键,一般多个表之间进行连接操作时需要用到主键。
因此并不需要为每个表建立主键,而且有些情况最好不使用主键

疑问3: 并不是每个表都可以任意选择存储引擎

外键约束(FOREIGN KEY)不能跨引擎使用。
MySQL 支持多种存储引擎,每一个表都可以指定一个不同的存储引擎,
需要注意的时: 外键约束时用来保证数据的参照完整性的,如果表之间需要关联外键,却指定了不同的存储引擎,那么这些表之间是不能创建外键约束的。
所以说,存储引擎的选择也不完全是随意的。

疑问4: 带 AUTO_INCREMENT 约束的字段值是从 1 开始的吗?

在 MySQL 中,默认 AUTO_INCREMENT 的初始值是 1,每新增一条记录,字段值自动加 1.
设置自增属性(AUTO_INCREMENT)的时候,还可以指定第一条插入记录的自增字段的值,这样新插入的记录的自增字段值从初始值开始递增,如在 tb_emp8 中插入第一条纪律,同时指定 id 值为 5,则以后插入的记录的 id 值就会从 6 开始往上增加。
添加唯一性的主键约束时,往往需要设置字段自动增加属性。