MySQL数据库 之 数据表的基本操作

时间:2022-06-20 14:06:40

在数据库中,数据表是其中最重要、最基本的操作对象,是数据存储的基本单位。
数据表被定义为列的集合,数据在表中是按照行和列的格式来存储的。每一行代表一条唯一的记录,每一列代表记录中的一个域。

一、 创建数据表

☆ 创建数据表

在创建数据表之前,我们需要选择一个数据库,在该数据库里面进行创建数据表等相关操作:

use db_name;  # 选择一个数据库,以便进行后续操作

创建数据表的语句为:

create table tb_name(
    字段名1 数据类型 [列的约束条件] [默认值],
    字段名2 数据类型 [列的约束条件] [默认值],
    ...
    [表的约束条件]
);
eg: 
# 创建一个名为 info 的数据表:
create table info( id int(10) , name varchar(30) , salary float , gender int(1) );

创建完成后,可以查看当前数据库中的数据表:

    >>> show tables;
    +-------------------+
    | Tables_in_test_db |
    +-------------------+
    | info              |
    +-------------------+
    1 row in set (0.00 sec)

☆ 使用主键约束

主键约束,要求主键列的数据唯一,且不允许为空。它能够唯一地标识表中的一条记录,可以结合外键类定义不同表之间的关系,并且可以加快数据库查询的速度。
主键分为两种类型:单字段主键和多字段联合主键。

○ 单字段主键

单字段主键由一个字段组成,SQL语句的格式分为下面两种情况:
① 在定义列的同时指定主键:

字段名 数据类型 primary key [默认值],
eg:
create table info( id int(10) primary key , # 定义id为主键 name varchar(30) , salary float , gender int(1) );

② 在定义完所有列之后指定主键:

[constraint <约束名>] primary key (字段名);
eg:
create table info( id int(10) , name varchar(30) , salary float , gender int(1) , primary key (id) # 定义id为主键 );
○ 多字段联合主键

主键由多个字段联合组成:

primary key (字段1, 字段2, [字段3...])
eg:
create table info( id int(10) , name varchar(30) , salary float , gender int(1) , primary key (id, name) # 定义 id、name 为联合主键 );

【注意】
并不是每一个表都需要一个主键,当多个表之间进行连接操作时需要用到主键,所以不需要为每个表建立主键,而且有些情况最好不使用主键。

☆ 使用外键约束

一个表可以有一个或多个外键。外键对应的是参照完整性,一个表的外键可以为空值。
首先,外键是表中的一个字段,它可以不是本表的主键,但对应的是另外一个表的主键。定义外键后,不允许删除在另一个表中具有关联关系的行。
外键的作用是保持数据的一致性、完整性。

对于外键来说,有主表和从表之分:
主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的按个表即使主表。
从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的那个表即是从表。
创建外键 的语法规则如下:

[constraint <外键名>] foreign key 字段名1 [, 字段名2, ...] references <主表名> 主键列1 [, 主键列2, ...]
eg:
# 创建一个 info 的数据表:
create table info( id int(10) primary key , name varchar(30) not null , salary float , gender int(1) );
# 创建一个 students 的数据表:
create table students( id int(10) primary key , name varchar(30) not null, class int(2) , constraint fk_info foreign key(info) references info(id) );
# 此时,students 表添加了名称为 fk_info 的外键约束,外键名称为 info , 其依赖于表 info 的主键 id。

【注意】
外键约束不能跨引擎使用。也就是说当从表要设置关联主表的外键约束时,主表的存储引擎与子表的必须一致,否则将导致设置外键约束失败。
所以说,存储引擎的设置并非完全随意。

☆ 使用非空约束

非空约束指字段的值不能为空。

字段名 数据类型 not null,
eg:
# 创建一个 info 的数据表,其中 name 字段的值不能为空:
create table info( id int(10) , name varchar(30) not null , salary float , gender int(1) );

【注意】
执行上面的命令后,后续在 name 字段插入值时,该值也不可为空。

☆ 使用唯一性约束

唯一性约束要求该列唯一,允许为空,但只能有一个为空(同样是唯一)。

○ 在定义完列之后直接指定唯一约束
字段名 数据类型 unique,
eg:
# 创建一个 info 的数据表,其中 name 字段的值唯一:
create table info( id int(10) , name varchar(30) unique , salary float , gender int(1) );
○ 在定义完所有列后指定唯一约束
[constraint <约束名>] unique (字段名)
eg:
# 创建一个 info 的数据表,其中 name 字段的值唯一:
create table info( id int(10) , name varchar(30) , salary float , gender int(1) , constraint uni_que unique(name) );

【注意】
unique 和 primary key 的区别:

一个表中可以有多个字段声明为 unique,但只能有一个 primary key声明,且声明为 primary key 的列不允许有空值,但是声明为 unique 的字段确允许有空值的存在(即使只能有一个为空)。

☆ 使用默认约束

默认约束——指定某列的默认值。

字段名 数据类型 default 默认值,
eg:
# 创建一个 info 的数据表,其中 gender 字段的默认值为 1 (男性):
create table info( id int(10) , name varchar(30) , salary float , gender int(1) default 1 , constraint uni_que unique(name) );

☆ 设置表的属性值自动增加

在MySQL中,默认 auto_increment 的初始值是 1,每新增一条记录,字段值自动加 1。
一个表只能有一个字段使用 auto_increment 约束,且该字段必须为主键或主键的一部分。

字段名 数据类型 auto_increment,
eg:
# 创建一个 info 的数据表,其中 id 字段的值自动增加:
create table info( id int(10) primary key auto_increment , name varchar(30) , salary float , gender int(1) default 1 );

【注意】
auto_increment 属性并不是只能从 1 开始自增,当我们定义该属性时,可以指定第一条插入记录的自增字段的初始值,这样后续插入的记录的自增值将从你指定的初始值开始自增。

二、 查看数据表结构

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

☆ 查看表 基本结构 语句: describe / desc

describe 或 desc 语句可以查看表的字段信息,其中包括:字段名、字段数据类型、是否为主键、是否有默认值等。

describe 表名;
或
desc 表名;
eg:
# 创建 info 数据表如下:
create table info(
 id int(10) ,
 name varchar(30) ,
 salary float ,
 gender int(1) 
);
# 查看表结构:
desc info;
# 返回的结果: +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| gender | int(1) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.03 sec)

☆ 查看表 详细结构 语句: show create table

此语句可以显示创建表时的 create table 语句。语法如下:

show create table tb_name[\G];

加上 ‘\G’后可以使显示的结果更加直观,易于查看。

eg:
# 查看 info 表的详细结构:
show create table info\G;
******** 1. row ********
       Table: info
Create Table: CREATE TABLE `info` ( `id` int(10) DEFAULT NULL, `name` varchar(30) DEFAULT NULL, `salary` float DEFAULT NULL, `gender` int(1) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)

三、 修改数据表

修改表指的是修改数据库中已经存在的数据表的 结构。MySQL使用 alter table 语句进行数据表的修改。

☆ 修改表名

alter table tb_name rename [to] <新表名>;
# to 可以省略也可以写上,没有影响
eg:
# 查看数据库中的数据表:
>>> show tables; +-------------------+
| Tables_in_test_db | +-------------------+
| info | +-------------------+
1 row in set (0.00 sec)
# 修改 info 的表名为 students_info : >>> alter table info rename to students_info;
>>> show tables; # 查看所有的数据表 +-------------------+
| Tables_in_test_db | +-------------------+
| students_info | +-------------------+
1 row in set (0.00 sec)
# 可以看到,此时 info 的数据表已经更名为 students_info,修改表名成功

☆ 修改字段的数据类型

修改字段的数据类型就是把字段的数据类型转换成另一种数据类型。

alter table tb_name modify 字段名 新数据类型;
eg:
# 查看 info 数据表的结构为:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| gender | int(1) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
# 修改 name 的字段类型为 varchar(50):
>>> alter table info modify name varchar(50);
# 查看 info 表的结构:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| gender | int(1) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
# 可以看到, name 字段的数据类型已经变更为 varchar(50)。

☆ 修改字段名

alter table tb_name change <旧字段名> <新字段名> <新数据类型>;

【注意】
可以将‘旧字段名’和‘新字段名’设置相同,这样就表示只修改数据类型;可以将‘新数据类型’设置为与原数据类型相同,这样表示只修改字段名,达到和‘modify’一样的效果。

eg:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| gender | int(1) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

# 1. 修改 gender 字段为 sex ,数据类型不变:
>>> alter table info change gender sex int(1);
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex | int(1) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

# 2. 修改 gender 字段的数据类型为 varchar(10),保持字段名不变:
>>> alter table info change gender gender varchar(10);
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| gender | varchar(10) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

【注意】
由于不同的数据类型在机器中的存储长度和方式并不相同,所以为避免影响数据,当数据表中已有数据时,不要轻易修改数据类型。

☆ 添加字段

alter table tb_name add <新字段名> <数据类型> [约束条件] [first | after 已存在字段名]

其中,‘first’会将新添加字段设置为表的第一个字段,’after 已存在字段名’则会将添加的字段置于‘已存在字段名’对应字段的后面。如果没有这两个选填的参数,则默认将新添加的字段置于数据表的最后。

eg:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex | varchar(10) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

# 1. 添加无完整性约束条件的字段
# 添加一个 class 字段,数据类型为 varchar(2):
>>> alter table info add class varchar(2);
>>> desc info: +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex    | varchar(10) | YES  |     | NULL    |       |
| class | varchar(2) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

# 2. 添加有完整性约束条件的字段
# 添加一个 grade 字段,数据类型为 varchar(2) 且不能为空:
>>> alter table info add grade varchar(2) not null;
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex    | varchar(10) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade | varchar(2) | NO | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

# 3. 在表的第一列添加一个字段
# 在第一列添加一个 first_col 字段,数据类型为 int(10): >>> alter table info add first_col int(10) first;
>>> desc info; +-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+
| first_col | int(10) | YES | | NULL | | | id | int(10) | YES | | NULL | | | name | varchar(50) | YES | | NULL | | | salary | float | YES | | NULL | | | sex | varchar(10) | YES | | NULL | | | class | varchar(2) | YES | | NULL | | | grade | varchar(2) | NO | | NULL | | +-----------+-------------+------+-----+---------+-------+ 7 rows in set (0.00 sec) # 4. 在表的指定列之后添加一个字段
# 在表的 id 列之后添加一个 third_col 字段,数据类型为 varchar(10): >>> alter table info add third_col varchar(10) after id;
>>> desc info; +-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+
| first_col | int(10) | YES | | NULL | | | id | int(10) | YES | | NULL | | | third_col | varchar(10) | YES  |     | NULL    |       |
| name      | varchar(50) | YES  |     | NULL    |       |
| salary    | float       | YES  |     | NULL    |       |
| sex       | varchar(10) | YES  |     | NULL    |       |
| class     | varchar(2)  | YES  |     | NULL    |       |
| grade | varchar(2) | NO | | NULL | | +-----------+-------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

☆ 删除字段

alter table tb_name drop <字段名>;
eg:
# 如上列的表结构,删除 third_col 字段: >>> alter table info drop third_col;
>>> desc info; +-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+
| first_col | int(10) | YES | | NULL | | | id | int(10) | YES | | NULL | | | name | varchar(50) | YES | | NULL | | | salary | float | YES | | NULL | | | sex | varchar(10) | YES | | NULL | | | class | varchar(2) | YES | | NULL | | | grade | varchar(2) | NO | | NULL | | +-----------+-------------+------+-----+---------+-------+ 7 rows in set (0.00 sec) # 删除其中的 first_col 字段: >>> alter table info drop first_col;
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex    | varchar(10) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade | varchar(2) | NO | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

☆ 修改字段的排列位置

alter table tb_name modify <字段名1> <数据类型> first | after <字段2>;

‘字段1’为要修改位置的字段,‘数据类型’为它的数据类型,参数若选择了 first,则将其修改为列表的第一列,若选择了‘after <字段2>’则表示要将其排列位置修改为‘字段2’列的后面一列。

eg:
# 现有表结构如下:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| sex    | varchar(10) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade | varchar(2) | NO | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

# 1. 将 sex 列修改为表的第一个字段
>>> alter table info modify sex varchar(10) first;
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| sex    | varchar(10) | YES  |     | NULL    |       |
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade | varchar(2) | NO | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

# 2. 将字段 salary 插入到字段 grade 后面:
>>> alter table info modify salary float after grade;
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| sex    | varchar(10) | YES  |     | NULL    |       |
| id     | int(10)     | YES  |     | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade  | varchar(2)  | NO   |     | NULL    |       |
| salary | float | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)

☆ 更改表的存储引擎

存储引擎是MySQL数据库中的数据存储在文件或内存中时采用的不同技术实现,我们最多可以为每张表选择不同的存储引擎。
语法:

alter table tb_name engine=<更改后的存储引擎名>;
eg:
# 1. 在更改数据表的存储引擎之前,需要先查看当前存储引擎:
>>> show create table info\G;
******** 1. row ********
       Table: info
Create Table: CREATE TABLE `info` (
  `sex` varchar(10) DEFAULT NULL,
  `id` int(10) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `class` varchar(2) DEFAULT NULL,
  `grade` varchar(2) NOT NULL,
  `salary` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

# 可以看到当前存储引擎为 InnoDB,现在我们将其修改为MyISAM:
>>> alter table info engine=MyISAM;
>>> show create table info\G;
******** 1. row ********
       Table: info
Create Table: CREATE TABLE `info` (
  `sex` varchar(10) DEFAULT NULL,
  `id` int(10) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `class` varchar(2) DEFAULT NULL,
  `grade` varchar(2) NOT NULL,
  `salary` float DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

☆ 删除表的外键约束

alter table tb_name drop foreign key <外键约束名>

‘<外键约束名>’指在定义表时 constraint 后面的参数。

# 查看 info 表的结构如下:
>>> desc info;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sex    | varchar(10) | YES  |     | NULL    |       |
| id     | int(10)     | NO   | PRI | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade  | varchar(2)  | NO   |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

# 创建数据表 info_slave 并设置名为 fk_info_id 的外键 info_id 关联 info 表的主键 id:
>>> create table info_slave(
    id int(10) primary key not null,
    name varchar(50),
    book_name varchar(100),
    info_id int(10),
    constraint fk_info_id foreign key (info_id) references info(id)
);

# 查看 info_slave 的结构:
>>> show create table info_slave\G;
******** 1. row ********
 Table: info_slave
Create Table: CREATE TABLE `info_slave` (
  `id` int(10) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `book_name` varchar(100) DEFAULT NULL,
  `info_id` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_info_id` (`info_id`),
  CONSTRAINT `fk_info_id` FOREIGN KEY (`info_id`) REFERENCES `info` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

# 可以看到我们成功添加了外键,现在我们将外键约束删除:
>>> alter table info_slave drop foreign key fk_info _id;
>>> show create table info_slave\G;
******** 1. row ********
 Table: info_slave
Create Table: CREATE TABLE `info_slave` (
  `id` int(10) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `book_name` varchar(100) DEFAULT NULL,
  `info_id` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_info_id` (`info_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

# 可以看到 info_slave 表中已经不存在外键,且原名为 fk_info_id 的外键约束删除成功。

四、 删除数据表

删除数据表的同时,表的定义和表中的所有数据均将被删除。所以在进行删除数据表的操作以前,最好将表中的数据做一个备份,以免造成无法挽回的后果。

☆ 删除没有被关联的表

drop table [if exists] 表1 [, 表2, ...];

如果要删除的数据表不存在,MySQL会报错,当加入 ‘if exists’参数后,会在删除前判断要被删除的表是否存在,如果存在则删除,如果不存在则会跳过该数据表继续向下执行,会报警告,但不会报错。

eg:
# 新建表 students :
>>> create table students(
 id int(10) primary key not null,
 name varchar(50), 
 gender int(1) default 1,
 age int(2) 
 );
>>> show tables; +-------------------+
| Tables_in_test_db | +-------------------+
| info              |
| info_slave | | students | +-------------------+ 3 rows in set (0.01 sec) # 将 students 表删除:
>>> drop table if exists students;
>>> show tables; +-------------------+
| Tables_in_test_db | +-------------------+
| info              |
| info_slave | +-------------------+
2 rows in set (0.00 sec)

如果想一次性删除多个数据表,只要将表名写在后面,中间用逗号隔开即可。

☆ 删除被其他表关联的主表

数据表之间存在外键关联的情况下,如果直接删除主表,将会失败,因为这样就破坏了参照完整性。
如果必须要删除,可以先删除与它关联的子表。但这样又会同时删除了两张表中的数据。如果我们还想保留子表的数据,我们应该怎么办呢?
想要单独的删除父表,我们就需要先将子表的外键约束条件取消,这样就可以单独将父表删除。

# 查看 info 表结构如下:
>>> desc info; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| sex    | varchar(10) | YES  |     | NULL    |       |
| id     | int(10)     | NO   | PRI | NULL    |       |
| name   | varchar(50) | YES  |     | NULL    |       |
| class  | varchar(2)  | YES  |     | NULL    |       |
| grade  | varchar(2)  | NO   |     | NULL    |       |
| salary | float | YES | | NULL | | +--------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

# 查看 info_slave 表结构如下: >>> desc info_slave;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+
| id      | int(10)     | NO   | PRI | NULL    |       |
| name    | varchar(50) | YES  |     | NULL    |       |
| info_id | int(10) | YES | MUL | NULL | | +---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

# 查看 info_slave 表的外键约束: >>> show create table info_slave\G;
******** 1. row ********
 Table: info_slave
Create Table: CREATE TABLE `info_slave` (
 `id` int(10) NOT NULL,
 `name` varchar(50) DEFAULT NULL,
 `info_id` int(10) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `fk_info_id` (`info_id`),
 CONSTRAINT `fk_info_id` FOREIGN KEY (`info_id`) REFERENCES `info` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

# 可以看到 info_slave 中的 info_id 字段是外键,关联着 info 表的主键 id。我们先取消 info_slave 表的外键约束: >>> alter table info_slave drop foreign key fk_info_id;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

# 表示上面的命令操作成功,现在我们开始删除主表 info :
# 删除之前我们先查看一下所有的数据表:
>>> show tables; +-------------------+
| Tables_in_test_db | +-------------------+
| info              |
| info_slave | +-------------------+
2 rows in set (0.00 sec)

>>> drop table info;
Query OK, 0 rows affected (0.01 sec)

至此,info 数据表被成功删除。