1、创建数据表
1.1、创建表的语法形式
数据表属于数据库,在创建数据表之前,应该使用语句“USE<数据库名>”指定操作是在哪个数据库中进行,如果没有选择数据库,就会抛出“No database selected”的错误。
create table <表名>
(
字段1,数据类型 [列界别约束条件] [默认值],
字段2,数据类型 [列界别约束条件] [默认值],
...
[表级别约束条件]
);
使用 CREATE TABLE创建表时,必须指定以下信息:
- 要创建的表的名称,不区分大小写,不能使用SQL语言中的关键字,如DROP、ALTER、INSERT等。
- 数据表中每一列(字段)的名称和数据类型,如果创建多列,就要用逗号隔开。
创建员工表tb_empl,结构如表所示。

创建数据库,SQL语句如下:
create database test_db;
选择创建表的数据库,SQL语句如下:
use test_db;
创建tb_emp1表,SQL语句为:
create table tb_emp1(
id int(11),
name varchar(25),
deptId int(11),
salary float
);
语句执行后,便创建了一个名称为tb_emp1的数据表,使用"SHOW TABLES;"语句查看数据表是否创建成功,SQL语句如下:
show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_emp1 |
+-------------------+
可以看到,test_db数据库中已经有了数据表tb_emp1,数据表创建成功。
1.2、使用主键约束
主键,又称主码,是表中一列或多列的组合。主键约束(PrimaryKey Constraint)要求主键列的数据唯一,并且不允许为空。主键能够唯一地标识表中的一条记录,可以结合外键来定义不同数据表之间的关系,并且可以加快数据库查询的速度。主键和记录之间的关系如同身份证和人之间的关系,它们之间是一一对应的。主键分为两种类型:
- 单字段主键
- 多字段联合主键。
1.2.1、单字段主键
主键由一个字段组成,SQL语句格式分为以下两种情况。
1. 在定义列的同时指定主键,语法规则如下:
字段名 数据类型 primary key [默认值]
定义数据表tb_emp2,其主键为id,SQL语句如下:
create table tb_emp2
(
id int(11) primary key,
name varchar(25),
deptId int(11),
salary float
);
2. 在定义完所有列之后指定主键:
[constraint <约束名>] primary key (字段名)
定义数据表tb_emp3,其主键为id,SQL语句如下:
create table tb_emp3
(
id int(11),
name varchar(25),
deptId int(11),
salary float,
constraint pk_id primary key (id)
);
上述两个例子执行后的结果是一样的,都会在id字段上设置主键约束。
1.2.2、多字段联合主键
主键由多个字段联合组成,语法规则如下:
primary key [字段1, 字段2, ..., 字段n]
定义数据表tb_emp4,假设表中间没有主键id,为了唯一确定一个员工,可以把name.deptld 联合起来作为主键,SQL语句如下:
create table tb_emp4
(
name varchar(25),
deptId int(11),
salary float,
primary key(name, deptId)
);
语句执行后,便创建了一个名称为tb_emp4的数据表,name字段和deptld字段组合在一起成为tb_emp4的多字段联合主键。
1.3、使用外键约束
外键用来在两个表的数据之间建立连接,可以是一列或者多列。一个表可以有一个或多个外键。外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一个外键值必须等于另一个表中主键的某个值。
外键:首先它是表中的一个字段,虽可以不是本表的主键,但要对应另外一个表的主键。外键的主要作用是保证数据引用的完整性,定义外键后,不允许删除在另一个表中具有关联关系的行。外键的作用是保持数据的一致性、完整性。例如,部门表tb_dept的主键是id,在员工表tb_emp5中有一个键deptld与这个id关联。
- 主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的那个表即是主表。
- 从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的那个表即是从表。
创建外键的语法规则如下:
[constraint <外键名>] foreign key 字段名1 [, 字段名2, ...]
references <主表名> 主键列1 [,主键列2,...]
“外键名”为定义的外键约束的名称,一个表中不能有相同名称的外键;“字段名”表示子表需要添加外键约束的字段列:“主表名”即被子表外键所依赖的表的名称:“主键列”表示主表中定义的主键列,或者列组合。
定义数据表tb_emp5,并在tb_emp5表上创建外键约束。
创建一个部门表tb_dept1,表结构如下所示,SQL语句如下:

create table tb_dept1
(
id int(11) primary key,
name varchar(22) not null,
location varchar(50)
);
定义数据表tb_emp5,让它的键作为外键关联到tb_dept1的主键id,SQL语句为:
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。
关联指的是在关系型数据库中相关表之间的联系。它是通过相容或相同的属性或属性组来表示的。子表的外键必须关联父表的主键,且关联字段的数据类型必须匹配,如果类型不一样,则创建子表时,就会出现错误“ERROR 1005 (HY000):Can’t create table ‘database.tablename’(errno: 150)”。
1.4、使用非空约束
非空约束(Not Null Constraint)指字段的值不能为空。对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统会报错。
非空约束的语法规则如下:
字段名 数据类型 not null
定义数据表tb_emp6,指定员工的名称不能为空,SQL语句如下:
create table tb_emp6
(
id int(11) primary key,
name varchar(25) not null,
deptId int(11),
salary float
);
1.5、使用唯一性约束
唯一性约束(Unique Constraint)要求该列唯一,允许为空,但只能出现一个空值。唯一约束可以确保一列或者几列不出现重复值。
唯一性约束的语法规则如下:
1. 在定义完列之后直接指定唯一约束,语法规则如下:
字段名 数据类型 UNIQUE
定义数据表tb_dept2,指定部门的名称唯一,SQL语句如下:
create table tb_dept2
(
id int(11) primary key,
name varchar(22) unique,
location varchar(50)
);
2. 在定义完所有列之后指定唯一约束,语法规则如下:
[CONSTRAINT <约束名>] UNIQUE(<字段名>)
定义数据表tb_dept3,指定部门的名称唯一,SQL语句如下:
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声明;声明为PRIMAYKEY的列不允许有空值,但是声明为UNIQUE的字段允许空值(NULL)的存在。
1.6、 使用默认约束
默认约束(Default Constraint)指定某列的默认值。如男性同学较多,性别就可以默认为‘男’。如果插入一条新的记录时没有为这个字段赋值,那么系统会自动为这个字段赋值为‘男’。
默认约束的语法规则如下:
字段名 数据类型 DEFAULT 默认值
定义数据表tb_emp7,指定员工的部门编号默认为1111,SQL语句如下:
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。
1.7、设置表的属性值自动增加
在数据库应用中,经常希望在每次插入新记录时,系统自动生成字段的主键值。可以通过为表主键添加AUTO_INCREMENT关键字来实现。默认的,在MySQL中AUTO_INCREMENT的初始值是1,每新增一条记录,字段值自动加1。一个表只能有一个字段使用AUTO_INCREMENT约束,且该字段必须为主键的一部分。AUTO_INCREMENT约束的字段可以是任何整数类型(TINYINT、SMALLIN、INT、BIGINT等)。
设置表的属性值自动增加的语法规则如下:
字段名 数据类型 AUTO_INCREMENT
定义数据表tb_emp8,指定员工的编号自动递增,SQL语句如下:
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。
例如,执行如下插入语句:
INSERT INTO tb_emp8 (name,salary)
VALUES('Lucy',1000), ('Lura',1200),('Kevin',1500);
这里使用INSERT声明向表中插入记录的方法,并不是SQL的标准语法,这种语法不一定被其他的数据库支持,只能在MySQL中使用。
语句执行完后,tb_emp8表中增加3条记录,在这里并没有输入id的值,但系统已经自动添加该值,使用SELECT命令查看记录,如下所示。
select * from tb_emp8;
+----+-------+--------+--------+
| id | name | deptId | salary |
+----+-------+--------+--------+
| 1 | Lucy | <null> | 1000.0 |
| 2 | Lura | <null> | 1200.0 |
| 3 | Kevin | <null> | 1500.0 |
+----+-------+--------+--------+
2、查看数据表结构
2.1、查看表基本结构语句DESCRIBE
DESCRIBE/DESC语句可以查看表的字段信息,其中包括字段名、字段数据类型、是否为主键、是否有默认值等。语法规则如下:
DESCRIBE 表名;
或者简写为:
DESC 表名;
分别使用DESCRIBE和DESC查看表tb_dept1和表tb_emp1的表结构。
查看tb_dept1表结构,SQL语句如下:
describe tb_dept1;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(22) | NO | | <null> | |
| location | varchar(50) | YES | | <null> | |
+----------+-------------+------+-----+---------+-------+
查看tb_emp1表结构,SQL语句如下:
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> | |
+--------+-------------+------+-----+---------+-------+
其中,各个字段的含义分别解释如下:
NULL:表示该列是否可以存储NULL值。Key:表示该列是否已编制索引。PRI表示该列是表主键的一部分;UNI表示该列是UNIQUE索引的一部分;MUL表示在列中某个给定值允许出现多次。
Default:表示该列是否有默认值,有的话指定值是多少。Extra:表示可以获取的与给定列有关的附加信息,例如AUTO_INCREMENT等。
2.2、查看表详细结构语句SHOW CREATE TABLE
SHOW CREATE TABLE语句可以用来显示创建表时的CREATE TABLE语句,语法格式如下:
SHOW CREATE TABLE <表名\G>;
使用SHOW CREATE TABLE语句,不仅可以查看表创建时候的详细语句,还可以查看存储引擎和字符编码。
如果不加‘\G’参数,显示的结果可能非常混乱,加上参数‘\G’之后,可使显示结果更加直观,易于查看。
使用SHOW CREATE TABLE查看表tb_emp1的详细信息,SQL语句如下:
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=utf8mb3 |
+---------+-----------------------------------------+
3、修改数据表
修改表指的是修改数据库中已经存在的数据表的结构。MySQL使用ALTER TABLE语句修改表。常用的修改表的操作有修改表名、修改字段数据类型或字段名、增加和删除字段、修改字段的排列位置、更改表的存储引擎、删除表的外键约束等
3.1、修改表名
MySQL是通过ALTER TABLE语句来实现表名的修改的,具体的语法规则如下:
ALTER TABLE <旧表名> RENAME [TO] <新表名>;
其中,TO为可选参数,使用与否均不影响结果。
将数据表tb_dept3改名为tb_deptment3。
执行修改表名操作之前,使用SHOWTABLES查看数据库中所有的表。
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 |
+-------------------+
使用ALTER TABLE将表tb_dept3改名为tb_deptment3,SQL语句如下:
ALTER TABLE tb_dept3 RENAME tb_deptment3;
语句执行之后,检验表tb_dept3是否改名成功。使用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 |
+-------------------+
经过比较可以看到,数据表列表中已经有了名称为tb_deptment3的表。
可以在修改表名称时使用DESC命令查看修改前后两个表的结构,修改表名并不修改表的结构,因此修改名称后的表和修改名称前的表的结构必然是相同的。
3.2、修改字段的数据类型
修改字段的数据类型,就是把字段的数据类型转换成另一种数据类型。在MySQL中修改字段数据类型的语法规则如下:
ALTER TABLE <表名> MODIFY <字段名> <数据类型>
其中,“表名”指要修改数据类型的字段所在表的名称,“字段名”指需要修改的字段,“数据类型”指修改后字段的新数据类型。
将数据表tb_dept1中name字段的数据类型由VARCHAR(22)修改成VARCHAR(30)。
执行修改表名操作之前,使用DESC查看tb_dept1表结构,结果如下:
desc tb_dept1;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(22) | NO | | <null> | |
| location | varchar(50) | YES | | <null> | |
+----------+-------------+------+-----+---------+-------+
可以看到现在name字段的数据类型为VARCHAR(22),下面修改其类型。输入如下SQL语句并执行:
ALTER TABLE tb_dept1 MODIFY name VARCHAR(30);
再次使用DESC查看表,结果如下:
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| location | varchar(50) | YES | | <null> | |
+----------+-------------+------+-----+---------+-------+
语句执行之后,检验会发现表tb_dept1表中name字段的数据类型已经修改成了VARCHAR(30),修改成功。
3.3、修改字段名
MySQL中修改表字段名的语法规则如下:
ALTER TABLE <表名> CHANGE <旧字段名> <新字段名> <新数据类型>;
其中,“旧字段名”指修改前的字段名;“新字段名”指修改后的字段名;“新数据类型”指修改后的数据类型,如果不需要修改字段的数据类型,将新数据类型设置成与原来一样即可,但数据类型不能为空。
将数据表tb_dept1中的location字段名称改为loc,数据类型保持不变,SQL语句如下:
ALTER TABLE tb_dept1 CHANGE location loc VARCHAR(50);
使用DESC查看表tb_dept1,会发现字段的名称已经修改成功,结果如下:
desc tb_dept1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| loc | varchar(50) | YES | | <null> | |
+-------+-------------+------+-----+---------+-------+
将数据表tb_dept1中的loc字段名称改为location,同时将数据类型变为VARCHAR(60),SQL语句如下:
ALTER TABLE tb_dept1 CHANGE loc location VARCHAR(60);
使用DESC查看表tb_dept1,会发现字段的名称和数据类型均已经修改成功,结果如下:
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
+----------+-------------+------+-----+---------+-------+
CHANGE也可以只修改数据类型,实现和MODIFY同样的效果,方法是将SQL语句中的“新字段名”和“旧字段名”设置为相同的名称,只改变“数据类型”。由于不同类型的数据在机器中存储的方式及长度并不相同,修改数据类型可能会影响到数据表中已有的数据记录,因此当数据库表中已经有数据时,不要轻易修改数据类型。
3.4、添加字段
随着业务需求的变化,可能需要在已经存在的表中添加新的字段。一个完整字段包括字段名、数据类型、完整性约束。添加字段的语法格式如下:
alter table <表名> add <新字段名> <数据类型> [约束条件] [first | after 已存在字段名];
新字段名为需要添加的字段的名称;“FIRST”为可选参数,其作用是将新添加的字段设置为表的第一个字段;“AFTER”为可选参数,其作用是将新添加的字段添加到指定的“已存在字段名”的后面。
“FIRST”或“AFTER已存在字段名”用于指定新增字段在表中的位置,如果SQL语句中没有这两个参数,则默认将新添加的字段设置为数据表的最后列。‘’
3.4.1、添加无完整性约束条件的字段
在数据表tb_dept1中添加一个没有完整性约束的INT类型的字段managerId(部门经理编号),SQL语句如下:
ALTER TABLE tb_dept1 ADD managerId INT(10);
使用DESC查看表tb_dept1,会发现在表的最后添加了一个名为managerId的INT类型的字段,结果如下:
desc tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
+-----------+-------------+------+-----+---------+-------+
3.4.2、添加有完整性约束条件的字段
在数据表tb_dept1中添加一个不能为空的VARCHAR(12)类型的字段column1,SQL语句如下:
alter table tb_dept1 add column1 varchar(12) not null;
使用DESC查看表tb_dept1,会发现在表的最后添加了一个名为column1的VARCHAR(12)类型且不为空的字段,结果如下:
desc tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
| column1 | varchar(12) | NO | | <null> | |
+-----------+-------------+------+-----+---------+-------+
3.4.3、在表的第一列添加一个字段
在数据表tb_dept1中添加一个INT(11)类型的字段column2,SQL语句如下:
alter table tb_dept1 add column2 int(11) first;
使用DESC查看表tb_dept1,会发现在表第一列添加了一个名为column2的INT(11)类型字段,结果如下:
desc tb_dept1;
You're about to run a destructive command.
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| column2 | int | YES | | <null> | |
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
| column1 | varchar(12) | NO | | <null> | |
+-----------+-------------+------+-----+---------+-------+
3.4.4、在表的指定列之后添加一个字段
在数据表tb_dept1中name列后添加一个INT(11)类型的字段column3,SQL语句如下:
alter table tb_dept1 add column3 int(11) after name;
使用DESC查看表tb_dept1,结果如下:
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> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
| column1 | varchar(12) | NO | | <null> | |
+-----------+-------------+------+-----+---------+-------+
可以看到,tb_dept1表中增加了一个名称为column3的字段,其位置在指定的name字段后面,添加字段成功。
3.5、删除字段
删除字段是将数据表中的某个字段从表中移除,语法格式如下:
ALTER TABLE <表名> DROP <字段名>;
“字段名”指需要从表中删除的字段的名称。
删除数据表tb_dept1表中的column2字段。
首先,执行删除字段之前,使用DESC查看tb_dept1表结构,结果如下:
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> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
| column1 | varchar(12) | NO | | <null> | |
+-----------+-------------+------+-----+---------+-------+
删除column2字段,SQL语句如下:
alter table tb_dept1 drop column2;
再次使用DESC查看表tb_dept1,结果如下:
desc tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| column3 | int | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
| column1 | varchar(12) | NO | | <null> | |
+-----------+-------------+------+-----+---------+-------+
可以看到,tb_dept1表中已经不存在名称为column2的字段,说明删除字段成功。
3.6、修改字段的排列位置
对于一个数据表来说,在创建的时候,字段在表中的排列顺序就已经确定了,但表的结构并不是完全不可以改变的,可以通过ALTER TABLE来改变表中字段的相对位置。语法格式如下:
ALTER TABLE <表名> MODIFY <字段1> <数据类型> FIRST|AFTER <字段2>;
- 其中,“字段1”指要修改位置的字段;
- “数据类型”指“字段1”的数据类型;
- “FIRST”为可选参数,指将“字段1”修改为表的第一个字段;
- “AFTER字段2”指将“字段1”插入到“字段2”后面。
3.6.1、修改字段为表的第一个字段
将数据表tb_deptl中的column1字段修改为表的第一个字段,SQL语句如下:
alter table tb_dept1 modify column1 varchar(12) first;
使用DESC查看表tb_dept1,发现字段column1已经被移至表的第一列,结果如下:
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> | |
| location | varchar(60) | YES | | <null> | |
| managerId | int | YES | | <null> | |
+-----------+-------------+------+-----+---------+-------+
3.6.2、修改字段到表的指定列之后
将数据表tb_dept1中的column1字段插入到location字段后面,SQL语句如下:
alter table tb_dept1 modify column1 varchar(12) after location;
使用DESC查看表tb_dept1,结果如下:
desc tb_dept1;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | <null> | |
| name | varchar(30) | YES | | <null> | |
| column3 | int | YES | | <null> | |
| location | varchar(60) | YES | | <null> | |
| column1 | varchar(12) | YES | | <null> | |
| managerId | int | YES | | <null> | |
+-----------+-------------+------+-----+---------+-------+
可以看到,tb_dept1表中的字段column1已经被移至location字段之后。
3.7、更改表的存储引擎
存储引擎是MySQL中的数据存储在文件或者内存中时采用的不同技术实现。可以根据自己的需要,选择不同的引擎,甚至可以为每一张表选择不同的存储引擎。MySQL中主要的存储引擎有MyISAM、InnoDB、MEMORY(HEAP)、BDB、FEDERATED等。可以使用“SHOW ENGINES;”语句查看系统支持的存储引擎。
下表列出了5.5.13版本的MySQL所支持的存储引擎。

更改表的存储引擎的语法格式如下:
ALTER TABLE <表名> ENGINE=<更改后的存储引擎名>;
将数据表tb_deptment3的存储引擎修改为MyISAM。
在修改存储引擎之前,先使用SHOWCREATE TABLE查看表tb_deptment3当前的存储引擎,结果如下:
show create table tb_deptment3;
+--------------+-----------------------------------------+
| Table | Create Table |
+--------------+-----------------------------------------+
| tb_deptment3 | 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=utf8mb3 |
+--------------+-----------------------------------------+
可以看到,表tb_deptment3当前的存储引擎为ENGINE=InnoDB,接下来修改存储引擎类型,输入如下SQL语句并执行:
alter table tb_deptment3 engine=MyISAM;
使用SHOW CREATE TABLE再次查看表tb_deptment3的存储引擎,发现表tb_deptment3的存储引擎变成了“MyISAM”,结果如下:
show create table tb_deptment3;
# 某些云数据库(阿里云 RDS、腾讯云)默认禁用 MyISAM
3.8、删除表的外键约束
对于数据库中定义的外键,如果不再需要,可以将其删除。外键一旦删除,就会解除主表和从表间的关联关系,MySQL中删除外键的语法格式如下:
ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>
“外键约束名”指在定义表时CONSTRAINT关键字后面的参数。
删除数据表tb_emp9中的外键约束。
首先创建表tb_emp9,创建外键deptId关联tb_dept1表的主键id,SQL语句如下:
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的结构,结果如下:
show create table tb_emp9;
+---------+--------------------------------------------------------------------------------+
| Table | Create Table |
+---------+--------------------------------------------------------------------------------+
| tb_emp9 | 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=utf8mb3 |
+---------+--------------------------------------------------------------------------------+
可以看到,已经成功添加了表的外键,下面删除外键约束,SQL语句如下:
alter table tb_emp9 drop foreign key fk_emp_dept;
执行完毕之后,将删除表tb_emp9的外键约束。使用SHOW CREATE TABLE再次查看表tb_emp9结构,结果如下:
show create table tb_emp9;
+---------+-----------------------------------------+
| Table | Create Table |
+---------+-----------------------------------------+
| tb_emp9 | 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=utf8mb3 |
+---------+-----------------------------------------+
可以看到,tb_emp9中已经不存在FOREIGNKEY,原有的名称为fk_emp_dept的外键约束删除成功。
4、删除数据表
删除数据表就是将数据库中已经存在的表从数据库中删除。注意,在删除表的同时,表的定义和表中所有的数据均会被删除。因此,在进行删除操作前,最好对表中的数据做一个备份,以免造成无法挽回的后果。
4.1、删除没有被关联的表
在MySQL中,使用DROP TABLE可以一次删除一个或多个没有被其他表关联的数据表。语法格式如下:
DROP TABLE [IF EXISTS]表1, 表2,…表n;
其中,“表n”指要删除的表的名称,后面可以同时删除多个表,只需将要删除的表名依次写在后面,相互之间用逗号隔开即可。如果要删除的数据表不存在,则MySQL会提示一条错误信息,“ERROR 1051 (42S02):Unknown table ‘表名’”。参数“IF EXISTS”用于在删除前判断删除的表是否存在,加上该参数后,再删除表的时候,如果表不存在,SQL语句可以顺利执行,但是会发出警告(warning)。
删除数据表tb_dept2,SQL语句如下:
DROP TABLE IF EXISTS tb_dept2;
语句执行完毕之后,使用SHOW TABLES命令查看当前数据库中所有的表,SQL语句如下:
show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_dept1 |
| tb_deptment3 |
| tb_emp1 |
| tb_emp2 |
| tb_emp3 |
| tb_emp4 |
| tb_emp5 |
| tb_emp6 |
| tb_emp7 |
| tb_emp8 |
| tb_emp9 |
+-------------------+
从执行结果可以看到,数据表列表中已经不存在名称为tb_dept2的表,删除操作成功。
4.2、删除被其他表关联的主表
在数据表之间存在外键关联的情况下,如果直接删除父表,结果会显示失败,原因是直接删除将破坏表的参照完整性。如果必须要删除,可以先删除与它关联的子表,再删除父表,只是这样就同时删除了两个表中的数据。有的情况下可能要保留子表,这时若要单独删除父表,只需将关联的表的外键约束条件取消,然后就可以删除父表了,下面讲解这种方法。
在数据库中创建两个关联表,首先创建表tb_dept2,SQL语句如下:
create table tb_dept2
(
id int(11) primary key,
name varchar(22),
location varchar(50)
);
接下来创建表tb_emp,SQL语句如下:
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)
);
可以看到,以上执行结果创建了两个关联表tb_dept2和表tb_emp。其中,tb_emp表为子表,具有名称为fk_emp_dept的外键约束;tb_dept2为父表,其主键id被子表tb_emp所关联。
删除被数据表tb_emp关联的数据表tb_dept2。
首先试着直接删除父表tb_dept2,输入如下删除语句:
drop table tb_dept2;
(3730, "Cannot drop table 'tb_dept2' referenced by a foreign key constraint 'fk_emp_dept' on table 'tb_emp'.")
如前所述,在存在外键约束时,主表不能被直接删除。
接下来,解除关联子表tb_emp的外键约束,SQL语句如下:
alter table tb_emp drop foreign key fk_emp_dept;
语句成功执行后,将取消表tb_emp和表tb_dept2之间的关联关系,此时,可以输入删除语句,将原来的父表tb_dept2删除,SQL语句如下:
drop table tb_dept2;
最后通过“SHOW TABLES;”查看数据表列表:
show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| tb_dept1 |
| tb_deptment3 |
| tb_emp |
| tb_emp1 |
| tb_emp2 |
| tb_emp3 |
| tb_emp4 |
| tb_emp5 |
| tb_emp6 |
| tb_emp7 |
| tb_emp8 |
| tb_emp9 |
+-------------------+
可以看到,数据表列表中已经不存在名称为tb_dept2的表。
4.5、MySQL 8.0的新特性——默认字符集改为utf8mb4
在MySQL 8.0版本之前,默认字符集为latin1,utf8字符集指向的是utf8mb3。网站开发人员在数据库设计的时候往往会将编码修改为utf8字符集。如果遗忘修改默认的编码,就会出现乱码的问题。从MySQL 8.0开始,数据库的默认编码改为utf8mb4,从而避免了上述的乱码问题。
下面通过案例来对比不同的版本中默认字符集的变化。
在MySQL 5.7版本中,查看数据库的默认编码,结果如下:
show variables like 'character_set_database';
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| character_set_database | latin1 |
+------------------------+--------+
1 row in set (0.01 sec)
在MySQL 8.0版本中,测试数据库的默认编码,结果如下:
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| character_set_database | utf8mb3 |
+------------------------+---------+
在MySQL 8.0版本中,查看数据表的默认编码,结果如下:
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=utf8mb3 |
+---------+-----------------------------------------+
4.6、MySQL 8.0的新特性——自增变量的持久化
在MySQL 8.0之前,自增主键AUTO_INCREMENT的值如果大于max(primary key)+1,在MySQL重启后,会重置AUTO_INCREMENT=max(primarykey)+1,这种现象在某些情况下会导致业务主键冲突或者其他难以发现的问题。
下面通过案例来对比不同的版本中自增变量是否持久化。
在MySQL 5.7版本中,测试步骤如下:
创建的数据表中包含自增主键的id字段,语句如下:
create table test1(
id int auto_increment primary key
);
插入4个空值,执行如下:
insert into test1 values(0), (0), (0), (0);
查询数据表test1中的数据,结果如下:
select * from test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
4 rows in set (0.00 sec)
删除id为4的记录,语句如下:
delete from test1
where id = 4;
再次插入一个空值,语句如下:
insert into test1 values(0);
查询此时数据表test1中的数据,结果如下:
select * from test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 5 |
+----+
从结果可以看出,虽然删除了id为4的记录,但是再次插入空值时,并没有重用被删除的4,而是分配了5。
删除id为5的记录,结果如下:
delete from test1
where id = 5;
重启数据库,重新插入一个空值。
insert into test1 values(0);
再次查询数据表test1中的数据,结果如下:
select * from test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
从结果可以看出,新插入的0值分配的是4,按照重启前的操作逻辑,此处应该分配6。出现上述结果的主要原因是自增主键没有持久化。
在MySQL 5.7系统中,对于自增主键的分配规则,是由InnoDB数据字典内部一个计数器来决定的,而该计数器只在内存中维护,并不会持久化到磁盘中。当数据库重启时,该计数器会通过下面这种方式初始化。
select max(ai_col)
from table_name for update;
在MySQL 8.0版本中,上述测试步骤最后一步的结果如下:
select * from test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 6 |
+----+
从结果可以看出,自增变量已经持久化了。下面讲述MySQL 8.0的解决方案。
MySQL 8.0将自增主键的计数器持久化到重做日志中。每次计数器发生改变,都会将其写入重做日志中。如果数据库重启,InnoDB会根据重做日志中的信息来初始化计数器的内存值。为了尽量减小对系统性能的影响,计数器写入到重做日志时并不会马上刷新数据库系统。
4.7、综合案例
创建数据库company,按照表4.4和表4.5给出的表结构在company数据库中创建两个数据表offices和employees,按照操作过程完成对数据表的基本操作。
offices表结构:

employees表结构:

1. 登录MySQL数据库。
打开windows命令行,输入登录用户名和密码:
C:\>mysql –h localhost -u root -p
Enter password: **
2. 创建数据库company。
创建数据库company的语句如下:
CREATE DATABASE company;
结果显示创建成功,在company数据库中创建表,必须先选择该数据库,输入语句如下:
use company;
3. 创建表offices。
创建表offices的语句如下:
create table offices
(
officeCode int(10) not null unique,
city varchar(50) not null,
address varchar(50) not null,
country varchar(50) not null,
postalCode varchar(15) not null,
primary key (officeCode)
);
执行成功之后,使用“SHOW TABLES;”语句查看数据库中的表,语句如下:
show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| offices |
+-------------------+
可以看到,数据库中已经有了数据表offices,创建成功。
4. 创建表employees。
创建表employees的语句如下:
create table employees
(
employeeNumber int(11) not null primary key auto_increment,
lastName varchar(50) not null,
firstName varchar(5) not null,
mobile varchar(25) not null,
officeCode int(10) not null,
jobTitle varchar(50) not null,
birth datetime,
note varchar(255),
sex varchar(5),
constraint office_fk foreign key(officeCode) references offices(officeCode)
);
执行成功之后,使用“SHOW TABLES;”语句查看数据库中的表,语句如下:
show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| employees |
| offices |
+-------------------+
可以看到,现在数据库中已经创建好了employees和offices两个数据表。要检查表的结构是否按照要求创建,可使用DESC语句,如果语句正确,则显示结果如下:
desc offices;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| officeCode | int | NO | PRI | <null> | |
| city | varchar(50) | NO | | <null> | |
| address | varchar(50) | NO | | <null> | |
| country | varchar(50) | NO | | <null> | |
| postalCode | varchar(15) | NO | | <null> | |
+------------+-------------+------+-----+---------+-------+
desc employees;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| mobile | varchar(25) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| birth | datetime | YES | | <null> | |
| note | varchar(255) | YES | | <null> | |
| sex | varchar(5) | YES | | <null> | |
+----------------+--------------+------+-----+---------+----------------+
5. 将表employees的mobile字段修改到officeCode字段后面。
修改字段位置,需要用到ALTER TABLE语句,输入如下语句:
alter table employees modify mobile varchar(25) after officeCode;
结果显示执行成功,使用DESC查看修改后的结果如下:
desc employees;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| mobile | varchar(25) | YES | | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| birth | datetime | YES | | <null> | |
| note | varchar(255) | YES | | <null> | |
| sex | varchar(5) | YES | | <null> | |
+----------------+--------------+------+-----+---------+----------------+
可以看到,mobile字段已经插入到officeCode字段的后面。
6. 将表employees的birth字段改名为employee_birth。
修改字段名,需要用到ALTER TABLE语句,输入语句如下:
alter table employees change birth employee_birth datetime;
结果显示执行成功,使用DESC查看修改后的结果如下:
desc employees;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| mobile | varchar(25) | YES | | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| employee_birth | datetime | YES | | <null> | |
| note | varchar(255) | YES | | <null> | |
| sex | varchar(5) | YES | | <null> | |
+----------------+--------------+------+-----+---------+----------------+
可以看到,表中只有employee_birth字段,已经没有名称为birth的字段了,修改名称成功。
7. 修改sex字段,数据类型为CHAR(1),非空约束。
修改字段数据类型,需要用到ALTER TABLE语句,输入语句如下:
alter table employees modify sex char(1) not null;
结果显示执行成功,使用DESC查看修改后的结果如下:
desc employees;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| mobile | varchar(25) | YES | | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| employee_birth | datetime | YES | | <null> | |
| note | varchar(255) | YES | | <null> | |
| sex | char(1) | NO | | <null> | |
+----------------+--------------+------+-----+---------+----------------+
从执行结果可以看到,sex字段的数据类型由前面的VARCHAR(5)修改为VARCHAR(1),且其Null列显示为NO,表示该列不允许空值,修改成功。
8. 删除字段note。
删除字段,需要用到ALTER TABLE语句,输入语句如下:
alter table employees drop note;
结果显示执行语句成功,使用“DES Cemployees;”查看语句执行后的结果:
desc employees;
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| mobile | varchar(25) | YES | | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| employee_birth | datetime | YES | | <null> | |
| sex | char(1) | NO | | <null> | |
+----------------+-------------+------+-----+---------+----------------+
9. 增加字段名favoriate_activity,数据类型为VARCHAR(100)。
增加字段,需要用到ALTER TABLE语句,输入语句如下:
alter table employees add favoriate_activity varchar(100);
结果显示执行语句成功,使用“DESCemployees;”查看语句执行后的结果:
desc employees;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| employeeNumber | int | NO | PRI | <null> | auto_increment |
| lastName | varchar(50) | NO | | <null> | |
| firstName | varchar(5) | NO | | <null> | |
| officeCode | int | NO | MUL | <null> | |
| mobile | varchar(25) | YES | | <null> | |
| jobTitle | varchar(50) | NO | | <null> | |
| employee_birth | datetime | YES | | <null> | |
| sex | char(1) | NO | | <null> | |
| favoriate_activity | varchar(100) | YES | | <null> | |
+--------------------+--------------+------+-----+---------+----------------+
可以看到,数据表employees中增加了一个 新的列favoriate_activity,数据类型为VARCHAR(100),允许空值,添加新字段成功。
10. 删除表offices。
在创建表employees时,设置了表的外键,该表关联了其父表offices的officeCode主键。如前面所述,删除关联表时,要先删除子表employees的外键约束,才能删除父表。因此,必须先删除employees表的外键约束。
删除employees表的外键约束,输入如下语句:
alter table employees drop foreign key office_fk;
其中,office_fk为employees表的外键约束名称,即创建外键约束时CONSTRAINT关键字后面的参数,结果显示语句执行成功,现在可以删除offices父表。
删除表offices,输入如下语句:
drop table offices;
结果显示执行删除操作成功,使用“SHOWTABLES;”语句查看数据库中的表,结果如下:
show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| employees |
+-------------------+
可以看到,数据库中已经没有名称为offices 的表了,删除表成功。
11. 修改表employees存储引擎为MyISAM。
修改表存储引擎,需要用到ALTER TABLE语句,输入语句如下:
alter table employees engine=MyISAM;
12. 将表employees名称修改为employees_info。
修改数据表名,需要用到ALTER TABLE语句,输入语句如下:
alter table employees rename employees_info;
结果显示执行语句成功,使用“SHOWTABLES;”语句查看执行结果:
show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| employees_info |
+-------------------+
可以看到数据库中已经没有名称为 employees的数据表。
4.8、常见问题
4.8.1、表删除操作须谨慎
表删除操作将把表的定义和表中的数据一起删除,并且MySQL在执行删除操作时,不会有任何的确认信息提示,因此执行删除操时应当慎重。在删除表前,最好对表中的数据进行备份,这样当操作失误时可以对数据进行恢复,以免造成无法挽回的后果。
同样的,在使用ALTER TABLE进行表的基本修改操作时,在执行操作过程之前,也应该确保对数据进行完整的备份,因为数据库的改变是无法撤销的,如果添加了一个不需要的字段,可以将其删除;相同的,如果删除了一个需要的列,该列下面的所有数据都将会丢失。
4.8.2、每一个表中都要有一个主键吗?
并不是每一个表中都需要主键,一般多个表之间进行连接操作时需要用到主键。因此并不需要为每个表建立主键,而且有些情况最好不使用主键。
4.8.3、并不是每个表都可以任意选择存储引擎
外键约束(FOREIGN KEY)不能跨引擎使用。MySQL支持多种存储引擎,每一个表都可以指定一个不同的存储引擎,需要注意的是:外键约束是用来保证数据的参照完整性的,如果表之间需要关联外键,却指定了不同的存储引擎,那么这些表之间是不能创建外键约束的。所以说,存储引擎的选择也不完全是随意的。
4.8.4、带AUTO_INCREMENT约束的字段值是从1开始的吗?
在MySQL中,默认AUTO_INCREMENT的初始值是1,每新增一条记录,字段值自动加1。设置自增属性(AUTO_INCREMENT)的时候,还可以指定第一条插入记录的自增字段的值,这样新插入的记录的自增字段值从初始值开始递增,如在tb_emp8中插入第一条记录,同时指定id值为5,则以后插入的记录的id值就会从6开始往上增加。添加唯一性的主键约束时,往往需要设置字段自动增加属性。
290

被折叠的 条评论
为什么被折叠?



