数据操作语言(DML),主要针对数据库里的表里的数据进行操作,用来定义数据内容信息(数据);

一、增加数据内容信息(insert)

添加命令语法格式:

#属于表内容信息变更操作,需要按照表结构预先定义好的字段信息插入
mysql> insert into <表名> [( <字段名1>[,..<字段名n > ])] values ( 1 )[, ( n )]

实际操作命令演示

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu1` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 查看stu1表结构
mysql> desc db15.stu1;
+-------+--------------------------+------+-----+---------+----------------+
| Field | Type                     | Null | Key | Default | Extra          |
+-------+--------------------------+------+-----+---------+----------------+
| id    | int                      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10)              | NO   |     | NULL    |                |
| age   | tinyint unsigned         | NO   |     | NULL    |                |
| dept  | enum('Linux','net','go') | NO   |     | Linux   |                |
+-------+--------------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#插入单行信息标准方法(信息输入不要重复,且特定信息不要为空)
mysql> insert into db15.stu1(id,name,age,dept) values(1,'aaa',35,'net');

#验证是否插入成功,观察到已经成功插入
mysql> select * from db15.stu1;
+----+------+-----+------+
| id | name | age | dept |
+----+------+-----+------+
|  1 | aaa  |  35 | net  |
+----+------+-----+------+
1 row in set (0.00 sec)

#验证不添加id信息,是否能实现自增
mysql> insert into db15.stu1(name,age,dept) values('bbb',30,'go');

#结果验证,观察到id列因为设置AUTO_INCREMENT会实现自增
mysql> select * from db15.stu1;
+----+------+-----+------+
| id | name | age | dept |
+----+------+-----+------+
|  1 | aaa  |  35 | net  |
|  2 | bbb  |  30 | go   |
+----+------+-----+------+
2 rows in set (0.00 sec)

#插入单行信息标准方法(自增列信息可以填入0null,表示默认实现自增效果)
mysql> insert into db15.stu1(id,name,age,dept) values(0,'aaa',35,'net sec');
mysql> insert into db15.stu1(id,name,age,dept) values(null,'aaa',35,'net sec');

#插入单行信息可以不含有表字段信息(需要对表结构属性熟悉),这里可以用0null填充来实现自增效果
mysql> insert into db15.stu1 values(0,'bbb',25,'linux');

#插入多行信息可以不含有表字段信息,这里可以用0null填充来实现自增效果
mysql> insert into db15.stu1 values(0,'ccc',2,'net'),(0,'ddd',1,'Linux');

#插入当行信息可以只含部分字段信息,但是省略字段信息必须具有自增特性  可以为空 或有默认值输入
mysql> insert into db15.stu1 values(0,'eee',32,'python,linux,net sec');

#插入中文信息
mysql> insert into db15.stu1 values(0,'中国人',32,'python,linux,net sec');

# 检查信息是否插入成功
mysql>  select * from db15.stu1;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  1 | aaa       |  35 |       |
|  2 | aaa       |  35 |       |
|  3 | aaa       |  35 |       |
|  4 | bbb       |  25 | Linux |
|  5 | ccc       |   2 |       |
|  6 | ddd       |   1 | Linux |
|  7 | eee       |  32 |       |
|  8 | 中国人    |  32 |       |
+----+-----------+-----+-------+
8 rows in set (0.00 sec)

拓展:

正常在插入表数据的时候,id值一般按照1,2,3,4,5...这样的顺序开始进行递增。有时候,我们可能在插入表数据的时候,id值按照奇数或偶数的顺序开始递增,遇到这里一般是起始偏移量和每次增加的步长有关系。

正常情况下,起始偏移量和每次增加的步长设置的值为:

# 正常情况下,每次增加的步长为1
mysql> SHOW VARIABLES LIKE 'auto_increment_increment';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
+--------------------------+-------+
1 row in set (0.00 sec)

# 正常情况下,起始偏移量为1
mysql> SHOW VARIABLES LIKE 'auto_increment_offset';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| auto_increment_offset | 1     |
+-----------------------+-------+
1 row in set (0.00 sec)

按照奇数顺序递增,起始偏移量和每次增加的步长设置的值为:

# 奇数顺序递增,每次增加的步长为2
mysql> SHOW VARIABLES LIKE 'auto_increment_increment';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 2     |
+--------------------------+-------+
1 row in set (0.00 sec)

# 奇数顺序递增,起始偏移量为1
mysql> SHOW VARIABLES LIKE 'auto_increment_offset';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| auto_increment_offset | 1     |
+-----------------------+-------+
1 row in set (0.00 sec)

按照偶数顺序递增,起始偏移量和每次增加的步长设置的值为:

# 偶数顺序递增,每次增加的步长为2
mysql> SHOW VARIABLES LIKE 'auto_increment_increment';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 2     |
+--------------------------+-------+
1 row in set (0.00 sec)

# 偶数顺序递增,起始偏移量为2
mysql> SHOW VARIABLES LIKE 'auto_increment_offset';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| auto_increment_offset | 2     |
+-----------------------+-------+
1 row in set (0.00 sec)

二、修改数据内容信息(update)

修改命令语法格式

# 属于表内容信息变更操作,需要按照表结构预先定义好的字段信息修改,并且按照条件修改,默认全表修改
mysql> update 表名 set 字段='修改后的值' where 条件;

实际操作命令演示:

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu2` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 自动生成 id=1 的记录
mysql> INSERT INTO db15.stu2 (name, age, dept) VALUES ('初始值', 20, 'Linux');

# 数据表数据修改命令语法,修改表数据内容标准方式,修改时一定要加条件信息(条件信息建议为主键或具有唯一性信息)
mysql> update db15.stu2 set name="zhangsan" where id=1;

# 检查信息是否修改成功
mysql> select * from db15.stu2;
+----+----------+-----+-------+
| id | name     | age | dept  |
+----+----------+-----+-------+
|  1 | zhangsan |  20 | Linux |
+----+----------+-----+-------+
1 row in set (0.00 sec)

知识扩展:禁止修改命令不加条件信息执行命令:

1、服务端禁止不带where条件操作数据库表有两种方法:

利用sql_safe_updates配置参数,表示在delete,update操作中:

没有where条件,当where条件中列没有索引可用,且无limit限制时会拒绝更新。

环境准备

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu3` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 自动生成 id=1 的记录
mysql> INSERT INTO db15.stu2 (name, age, dept) VALUES ('初始值', 20, 'Linux');

方法一:临时生效

# 说明:这里执行完成后,并不会立即生效,必须退出再登录才会生效
mysql> set global sql_safe_updates=1;

#退出重新登录生效
mysql> quit
[root@master ~]# mysql
mysql> select @@sql_safe_updates;
+--------------------+
| @@sql_safe_updates |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

#验证测试,观察到不带where查询则无法正常执行sql语句
mysql> update db15.stu2 set name='abc';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

#使用where语句正常执行sql语句
mysql> update db15.stu2 set name='abc' where id=1;

#验证测试,观察到已正常修改
mysql> select * from db15.stu2;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  1 | abc       |  20 | Linux |
|  2 | 初始值    |  20 | Linux |
+----+-----------+-----+-------+
2 rows in set (0.00 sec)

方法二:永久生效

# 修改配置文件
[root@master ~]# vim /data/3306/data/my.cnf
[mysql]
socket=/tmp/mysql.sock
default-character-set=utf8mb4

[mysqld]
init-file=/opt/init.sql
port=3306
server_id=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
innodb_fast_shutdown=0
character-set-server=utf8mb4

#生成权限参数配置文件并进行赋权
[root@master ~]# echo 'set global sql_safe_updates=1;' >/opt/init.sql
[root@master ~]# chmod +x /opt/init.sql

#重启mysql
[root@master ~]# systemctl restart mysqld

#验证
[root@master ~]# mysql -e "select @@global.sql_safe_updates"
+---------------------------+
| @@global.sql_safe_updates |
+---------------------------+
|                         1 |
+---------------------------+

2、客户端禁止不带where条件操作数据库表有两种方法:

环境准备

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu4` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 自动生成 id=1 的记录
mysql> INSERT INTO db15.stu4 (name, age, dept) VALUES ('初始值', 20, 'Linux');

方法一:把safe_updates=1加入到my.cnf的client标签下

# 重新修改配置文件
[root@master ~]# vim /data/3306/data/my.cnf
[mysql]
socket=/tmp/mysql.sock
default-character-set=utf8mb4
sql_safe_updates=1

[mysqld]
init-file=/opt/init.sql
port=3306
server_id=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
innodb_fast_shutdown=0
character-set-server=utf8mb4

#重启mysql
[root@master ~]# systemctl restart mysqld

# 配置效果展示
mysql> update db15.stu4 set name='abc';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

#使用where语句正常执行sql语句
mysql> update db15.stu4 set name='abc' where id=1;

#验证测试,观察到已正常修改
mysql> select * from db15.stu4;
+----+------+-----+-------+
| id | name | age | dept  |
+----+------+-----+-------+
|  1 | abc  |  20 | Linux |
+----+------+-----+-------+
1 row in set (0.00 sec)

方法二:设置数据库别名操作方式,-U, --safe-updates Only allow UPDATE and DELETE that uses keys表示以安全更新模式登录数据库,并放入/etc/profile永久生效。

#添加变名
[root@master ~]# alias mysql='mysql -U'

#退出并重新进行登录
[root@master ~]# mysql

#配置效果展示
mysql> update db15.stu4 set name='abc';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

#使用where语句正常执行sql语句
mysql> update db15.stu4 set name='bbb' where id=1;

#验证测试,观察到已正常修改
mysql> select * from db15.stu4;
+----+------+-----+-------+
| id | name | age | dept  |
+----+------+-----+-------+
|  1 | bbb  |  20 | Linux |
+----+------+-----+-------+
1 row in set (0.00 sec)

三、删除数据库中数据信息(delete)

环境准备

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu5` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 连续插入数据
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 20, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 30, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 40, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 50, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 60, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 70, 'Linux');
mysql> INSERT INTO db15.stu5 (name, age, dept) VALUES ('初始值', 80, 'Linux');

# 验证
mysql> select * from db15.stu5;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  1 | 初始值    |  20 | Linux |
|  2 | 初始值    |  30 | Linux |
|  3 | 初始值    |  40 | Linux |
|  4 | 初始值    |  50 | Linux |
|  5 | 初始值    |  60 | Linux |
|  6 | 初始值    |  70 | Linux |
|  7 | 初始值    |  80 | Linux |
+----+-----------+-----+-------+
7 rows in set (0.00 sec)

删除命令语法格式:

# 数据表数据删除命令语法,属于表内容信息变更操作,需要按照表结构预先定义好的字段信息删除,并且按照条件删除,默认全表删除
mysql> delete from 表名 where 表达式;

实际操作命令演示:

# 删除表信息时,如果不加条件会进行逐行删除全表信息(效率比较慢)
mysql> \q

# 删除id小于3的记录()
mysql> delete from db15.stu5 where id<3;

# 删除后进行验证,观察到删除成功
mysql> select * from db15.stu5;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  3 | 初始值    |  40 | Linux |
|  4 | 初始值    |  50 | Linux |
|  5 | 初始值    |  60 | Linux |
|  6 | 初始值    |  70 | Linux |
|  7 | 初始值    |  80 | Linux |
+----+-----------+-----+-------+
5 rows in set (0.00 sec)

# 在上面的基础上继续执行下面语句,删除id值大于0且age的值为40或者50
mysql> DELETE FROM db15.stu5 WHERE (age = 40 OR age = 50) AND id > 0;

# 删除后进行验证,观察到id值大于0且age的值为40或者50删除成功
mysql> select * from db15.stu5;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  5 | 初始值    |  60 | Linux |
|  6 | 初始值    |  70 | Linux |
|  7 | 初始值    |  80 | Linux |
+----+-----------+-----+-------+
3 rows in set (0.00 sec)

# 删除整表内容
mysql> delete from db15.stu5 where id > 0;

# 检查信息是否删除成功
mysql> select * from db15.stu5;
Empty set (0.00 sec)

删除数据库信息扩展:伪删除操作

由于执行删除语句信息时,有可能会对一些业务数据造成影响,甚至可能会将表中所有数据清空,虽然可以通过日志信息恢复(闪回)

但是整体操作过程还是比较危险的,因此在进行数据信息删除操作时,可以利用伪删除操作代替真实删除操作;

一般在数据库中删除数据信息,是因为从业务层面有些数据不想被查询获取到,伪删除就是不让查询时可以获取想要删除的数据;

伪删除的本质:利用update替代delete

可以在相应表中添加状态列信息,可以将状态列设置为:1表示存在 0表示不存在

在进行伪删除操作时,只是将状态列信息改为0,但是并没有把相应行的数据信息删除,但是在查询时可以忽略状态列为0的信息;

这样可以有效规避误删除操作对业务数据的影响,万一伪删除操作有问题,可以再将状态列信息0改为1即可

环境准备

# 创建库db15
mysql> create database db15;

# 创建表
mysql> CREATE TABLE `db15`.`stu6` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键列',
`name` VARCHAR(10) NOT NULL,
`age` TINYINT UNSIGNED NOT NULL,
`dept` ENUM('Linux', 'net', 'go') NOT NULL DEFAULT 'Linux',
PRIMARY KEY (`id`));

# 插入数据
mysql> INSERT INTO db15.stu6 (name, age, dept) VALUES ('初始值', 20, 'Linux');

# 验证
mysql> select * from db15.stu6;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  1 | 初始值    |  20 | Linux |
+----+-----------+-----+-------+
1 row in set (0.00 sec)

情况一:真实删除数据信息操作举例

# 删除id=1的记录()
mysql> delete from db15.stu6 where id=1;

# 真实删除后进行验证
mysql> select * from db15.stu6;
Empty set (0.00 sec)

# 数据还原
mysql> INSERT INTO db15.stu6 (id, name, age, dept) VALUES ('1', '初始值', 20, 'Linux');

# 数据还原进行验证
mysql> select * from db15.stu6;
+----+-----------+-----+-------+
| id | name      | age | dept  |
+----+-----------+-----+-------+
|  1 | 初始值    |  20 | Linux |
+----+-----------+-----+-------+
1 row in set (0.00 sec)

情况二:伪删除数据信息操作举例,在原有表中添加新的状态列

# db15.stu6这个表新增一个名为state的属性
mysql> alter table db15.stu6 add state tinyint not null default 1;

#将原本删除列信息的状态改为0,实现伪删除效果
mysql> update db15.stu6 set state=0 where id=1;

#实现查询时不要获取状态为0的信息,即不查看获取伪删除数据信息
mysql> select * from db15.stu6 where state=1;
Empty set (0.00 sec)

企业数据库面试题目分析练习:

01 请解释说明以下语句之间的区别?

drop table stu;
truncate table stu;
delete from stu;

问题解答分析:

区别分析 drop table stu; truncate table stu; delete from stu;
功能效果 删除表结构+数据 删除表数据(释放空间) 删除表数据(标记删除)
删除逻辑 彻底删除 物理删除(段区页层面删除) 逻辑删除(逐行删除)
删除效率 效率快(和数据量无关) 效率快(和数据量无关) 效率慢(和数据量有关)
自增影响 新增自增序列 重置自增序列(释放高水位线) 延续自增序列
数据恢复? 利用日志文件恢复 利用备份恢复/延时从库恢复 利用日志文件恢复(快速)

知识扩展:自增列信息值调整方法:

mysql> alter table stu auto_increment=10;