数据操作语言(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)
#插入单行信息标准方法(自增列信息可以填入0或null,表示默认实现自增效果)
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');
#插入单行信息可以不含有表字段信息(需要对表结构属性熟悉),这里可以用0或null填充来实现自增效果
mysql> insert into db15.stu1 values(0,'bbb',25,'linux');
#插入多行信息可以不含有表字段信息,这里可以用0或null填充来实现自增效果
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;