目录
- 一、插入操作 --- insert
- 1.1 单行指定列插入&&单行全列插入
- 1.2 多行指定列插入&&多行全列插入
- 1.3 插入否则更新 duplicate key update
- 1.4 删除并替换 replace
- 二、查询操作 --- select
- 2.1 基本查询
- 2.2 where条件
- 2.3 案例演示
- 2.4 排序(order by)
- 2.5 limit筛选分页结果
- 三、更新操作 --- update
- 四、删除操作 --- delete
- 4.1截断表(TRUNCATE)
- 4.2 delete与truncate区别
CRUD : 四种操作
- Create(创建),
- Retrieve(读取),
- Update(更新),
- Delete(删除)
一、插入操作 — insert
创建一张学生表
-- 创建一张学生表
mysql> create table students(
-> id int unsigned primary key auto_increment,
-> sn int unsigned unique key,
-> name varchar(20) not null,
-> qq varchar(20) unique key);
1.1 单行指定列插入&&单行全列插入
-- 单行指定列插入 数据必须一一对应
mysql> insert into students(sn,name,qq)values(12,'貂蝉','987654321');
Query OK, 1 row affected (0.01 sec)
-- 单行全列插入 所有列的数据都要插入
mysql> insert into students values(5,126,'孙悟空','123456789');
Query OK, 1 row affected (0.00 sec)
查询展示
1.2 多行指定列插入&&多行全列插入
-- 多行指定列插入
mysql> insert into students(sn,name,qq)values(130,'张三','111111111'),(131,'李四','222222222'),(132,'王五','333333333');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
-- 多行全列插入
mysql> insert students values(20,140,'小刚','7777777'),(21,141,'小红','8888888'),(22,142,'小米','9999999');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
查询展示
1.3 插入否则更新 duplicate key update
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败
-- 主键冲突
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师');
ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'
-- 唯一键冲突
INSERT INTO students (sn, name) VALUES (20001, '曹阿瞒');
ERROR 1062 (23000): Duplicate entry '20001' for key 'sn'
可以选择性的进行同步更新操作 语法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
插入主键冲突把插入操作该为更新操作
-- 发生主键冲突
mysql> insert into students values(7,15,'盘古','123123123');
ERROR 1062 (23000): Duplicate entry '7' for key 'PRIMARY'
-- 插入变更新
mysql> insert into students values(7,15,'盘古','123123123') on duplicate key update sn=7,name='张良',qq='456456456';
Query OK, 2 rows affected (0.01 sec)
1.4 删除并替换 replace
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
mysql> replace into students (sn,name,qq)values(143,'aa','4564455');
Query OK, 1 row affected (0.01 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
二、查询操作 — select
2.1 基本查询
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
创建一张表
-- 创建表结构
CREATE TABLE exam_result (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL COMMENT '同学姓名',
chinese float DEFAULT 0.0 COMMENT '语文成绩',
math float DEFAULT 0.0 COMMENT '数学成绩',
english float DEFAULT 0.0 COMMENT '英语成绩'
);
-- 插入测试数据
INSERT INTO exam_result (name, chinese, math, english) VALUES
('唐三藏', 67, 98, 56),
('孙悟空', 87, 78, 77),
('猪悟能', 88, 98, 90),
('曹孟德', 82, 84, 67),
('刘玄德', 55, 85, 45),
('孙权', 70, 73, 78),
('宋公明', 75, 65, 30);
全列查询
– 通常情况下不建议使用 * 进行全列查询
– 1. 查询的列越多,意味着需要传输的数据量越大;
– 2. 可能会影响到索引的使用。
指定列查询
--指定列的顺序不需要按定义表的顺序来
SELECT id, name, english FROM exam_result;
查询字段为表达式
表达式是一个数字 10
-- 表达式为多个字段
SELECT id, name, chinese+math+english FROM exam_result;
为查询结果指定别名
结果去重distinct
select distinct math from exam_result;
2.2 where条件
比较运算符:
逻辑条件运算符:
2.3 案例演示
- 英语不及格的同学及英语成绩 ( < 60 )
mysql> select name,english from exam_result where english<60;
+-----------+---------+
| name | english |
+-----------+---------+
| 唐三藏 | 56 |
| 刘玄德 | 45 |
| 宋公明 | 30 |
+-----------+---------+
3 rows in set (0.00 sec)
- 语文成绩在 [80, 90] 分的同学及语文成绩
mysql> select name,chinese from exam_result where chinese>=80 and chinese<=90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87 |
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
3 rows in set (0.00 sec)
mysql> select name,chinese from exam_result where chinese between 80 and 90;
+-----------+---------+
| name | chinese |
+-----------+---------+
| 孙悟空 | 87 |
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
3 rows in set (0.00 sec)
- 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
mysql> select name,math from exam_result where math=58 or math=59 or math=98 or math=99+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
2 rows in set (0.00 sec)
mysql> select name,math from exam_result where math in (58,59,98,99);
+-----------+------+
| name | math |
+-----------+------+
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
2 rows in set (0.00 sec)
- 姓孙的同学 及 孙某同学
mysql> select name from exam_result where name like '孙%';
+-----------+
| name |
+-----------+
| 孙悟空 |
| 孙权 |
+-----------+
2 rows in set (0.00 sec)
mysql> select name from exam_result where name like '孙_';
+--------+
| name |
+--------+
| 孙权 |
+--------+
1 row in set (0.00 sec)
- 语文成绩好于英语成绩的同学
mysql> select name,english,chinese from exam_result where chinese>english;
+-----------+---------+---------+
| name | english | chinese |
+-----------+---------+---------+
| 唐三藏 | 56 | 67 |
| 孙悟空 | 77 | 87 |
| 曹孟德 | 67 | 82 |
| 刘玄德 | 45 | 55 |
| 宋公明 | 30 | 75 |
+-----------+---------+---------+
5 rows in set (0.00 sec)
- 总分在 200 分以下的同学
mysql> select name'姓名',chinese+math+english'总分' from exam_result where chinese+math+english>200;
+-----------+--------+
| 姓名 | 总分 |
+-----------+--------+
| 唐三藏 | 221 |
| 孙悟空 | 242 |
| 猪悟能 | 276 |
| 曹孟德 | 233 |
| 孙权 | 221 |
+-----------+--------+
5 rows in set (0.00 sec)
下面是错误的方式
select name,chinese+english+math total from exam_result where total<200;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'
--这样写回报错 原因是 先找到表 根据条件 筛选东西 顺序的第一步不认识total
--所以错误
执行顺序
- 语文成绩 大于80并且不姓孙的同学
mysql> select name,chinese from exam_result where chinese>80 and name not like '孙%';
+-----------+---------+
| name | chinese |
+-----------+---------+
| 猪悟能 | 88 |
| 曹孟德 | 82 |
+-----------+---------+
2 rows in set (0.00 sec)
- 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 >80
mysql> select name,chinese,math,english,chinese+math+english from exam_result where (chinese+math+english>200 and chinese<math and english>80) or (name like '孙_');
+-----------+---------+------+---------+----------------------+
| name | chinese | math | english | chinese+math+english |
+-----------+---------+------+---------+----------------------+
| 猪悟能 | 88 | 98 | 90 | 276 |
| 孙权 | 70 | 73 | 78 | 221 |
+-----------+---------+------+---------+----------------------+
2 rows in set (0.00 sec)
- NULL查询
mysql> select * from exam_result where name is null;
Empty set (0.00 sec)
2.4 排序(order by)
-- ASC 为升序(从小到大)默认为升序
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
-- NULL值比任何值都要小
- 同学姓名及数学成绩,按数学成绩升序显示
mysql> select name,math from exam_result order by math asc;
+-----------+------+
| name | math |
+-----------+------+
| 宋公明 | 65 |
| 孙权 | 73 |
| 孙悟空 | 78 |
| 曹孟德 | 84 |
| 刘玄德 | 85 |
| 唐三藏 | 98 |
| 猪悟能 | 98 |
+-----------+------+
7 rows in set (0.00 sec)
- 查询同学姓名各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
mysql> select name,math,english,chinese from exam_result order by math desc,english asc,chinese asc;
+-----------+------+---------+---------+
| name | math | english | chinese |
+-----------+------+---------+---------+
| 唐三藏 | 98 | 56 | 67 |
| 猪悟能 | 98 | 90 | 88 |
| 刘玄德 | 85 | 45 | 55 |
| 曹孟德 | 84 | 67 | 82 |
| 孙悟空 | 78 | 77 | 87 |
| 孙权 | 73 | 78 | 70 |
| 宋公明 | 65 | 30 | 75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)
- 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示、
mysql> select name,math from exam_result where name like '孙%' or name like '曹%' order by math desc;
+-----------+------+
| name | math |
+-----------+------+
| 曹孟德 | 84 |
| 孙悟空 | 78 |
| 孙权 | 73 |
+-----------+------+
3 rows in set (0.00 sec)
- 查询同学及总分,由低到高
mysql> select name,math+chinese+english as total from exam_result order by total;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 170 |
| 刘玄德 | 185 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 曹孟德 | 233 |
| 孙悟空 | 242 |
| 猪悟能 | 276 |
+-----------+-------+
7 rows in set (0.00 sec)
为什么这里可以用别名了呢
2.5 limit筛选分页结果
– 数据显示起始下标为 0
– 从 s 开始(下标从0开始),筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT s, n
–
– 从 0 开始,筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n;
–
– 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n OFFSET s;
从位置s开始,偏移n个位置
mysql> select * from exam_result limit 3;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 78 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
mysql> select * from exam_result limit 2,3;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 82 | 84 | 67 |
| 5 | 刘玄德 | 55 | 85 | 45 |
+----+-----------+---------+------+---------+
3 rows in set (0.01 sec)
mysql> select * from exam_result limit 3 offset 2;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 82 | 84 | 67 |
| 5 | 刘玄德 | 55 | 85 | 45 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)
三、更新操作 — update
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
对查询到的列值结果进行更新
- 将孙悟空同学的数学成绩变更为 80 分
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 78 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 82 | 84 | 67 |
| 5 | 刘玄德 | 55 | 85 | 45 |
| 6 | 孙权 | 70 | 73 | 78 |
| 7 | 宋公明 | 75 | 65 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
mysql> update exam_result set math=80 where name='孙悟空';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 80 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 82 | 84 | 67 |
| 5 | 刘玄德 | 55 | 85 | 45 |
| 6 | 孙权 | 70 | 73 | 78 |
| 7 | 宋公明 | 75 | 65 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
mysql> update exam_result set math=60,chinese=70 where name='曹孟德';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 67 | 98 | 56 |
| 2 | 孙悟空 | 87 | 80 | 77 |
| 3 | 猪悟能 | 88 | 98 | 90 |
| 4 | 曹孟德 | 70 | 60 | 67 |
| 5 | 刘玄德 | 55 | 85 | 45 |
| 6 | 孙权 | 70 | 73 | 78 |
| 7 | 宋公明 | 75 | 65 | 30 |
+----+-----------+---------+------+---------+
7 rows in set (0.00 sec)
- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
mysql> select name,math+chinese+english total from exam_result order by total limit 0,3;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 170 |
| 刘玄德 | 185 |
| 曹孟德 | 197 |
+-----------+-------+
mysql> update exam_result set math=math+30 order by math+chinese+english asc limit 3;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select name,math+chinese+english total from exam_result order by total limit 0,3;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 200 |
| 刘玄德 | 215 |
| 唐三藏 | 221 |
+-----------+-------+
3 rows in set (0.00 sec)
mysql> select name,math+chinese+english total from exam_result order by total;
+-----------+-------+
| name | total |
+-----------+-------+
| 宋公明 | 200 |
| 刘玄德 | 215 |
| 唐三藏 | 221 |
| 孙权 | 221 |
| 曹孟德 | 227 |
| 孙悟空 | 244 |
| 猪悟能 | 276 |
+-----------+-------+
7 rows in set (0.00 sec)
- 将所有同学的语文成绩更新为原来的 2 倍
mysql> update exam_result set chinese=chinese*2;
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7 Changed: 7 Warnings: 0
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 134 | 98 | 56 |
| 2 | 孙悟空 | 174 | 80 | 77 |
| 3 | 猪悟能 | 176 | 98 | 90 |
| 4 | 曹孟德 | 140 | 90 | 67 |
| 5 | 刘玄德 | 110 | 115 | 45 |
| 6 | 孙权 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
四、删除操作 — delete
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
- 删除孙悟空同学的考试成绩
mysql> delete from exam_result where name='孙悟空';
Query OK, 1 row affected (0.01 sec)
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name | chinese | math | english |
+----+-----------+---------+------+---------+
| 1 | 唐三藏 | 134 | 98 | 56 |
| 3 | 猪悟能 | 176 | 98 | 90 |
| 4 | 曹孟德 | 140 | 90 | 67 |
| 5 | 刘玄德 | 110 | 115 | 45 |
| 6 | 孙权 | 140 | 73 | 78 |
| 7 | 宋公明 | 150 | 95 | 30 |
+----+-----------+---------+------+---------+
- 删除整张表
mysql> CREATE TABLE for_delete (
-> id INT PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(20)
-> );
mysql> INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
mysql> select * from for_delete;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
mysql> delete from for_delete;
mysql> select * from for_delete;
mysql> INSERT INTO for_delete (name) VALUES ('D');
mysql> select * from for_delete;
+----+------+
| id | name |
+----+------+
| 4 | D |
+----+------+
注意:删除整张表删除的只是数据,属于DML语言,删除表中数据之后,AUTO_INCREMENT的值不会被重置,沿着上一次的数据接着自增
4.1截断表(TRUNCATE)
- 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
- 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚
- 会重置 AUTO_INCREMENT 项
TRUNCATE [TABLE] table_name
测试
mysql> create table for_truncate(
-> id int primary key auto_increment,
-> name varchar(30));
Query OK, 0 rows affected (0.08 sec)
mysql> INSERT INTO for_truncate (name) VALUES ('A'), ('B'), ('C');
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
3 rows in set (0.00 sec)
查看表结构 删除后再次查看
mysql> show create table for_truncate \G;
*************************** 1. row ***************************
Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> truncate for_truncate;
Query OK, 0 rows affected (0.03 sec)
mysql> show create table for_truncate \G;
*************************** 1. row ***************************
Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
自增id变更
mysql> insert into for_truncate(name) values('d');
Query OK, 1 row affected (0.00 sec)
mysql> select * from for_truncate;
+----+------+
| id | name |
+----+------+
| 1 | d |
+----+------+
1 row in set (0.00 sec)
4.2 delete与truncate区别
删除操作的区别:
- DELETE语句用于逐行地删除表中的数据记录。它是一个事务操作,可以在执行时指定条件,并且只删除满足条件的行。DELETE操作可以回滚,因此可以撤消对表数据的删除操作。
TRUNCATE语句用于快速删除表中的所有数据。它是一个DDL(数据定义语言)操作,它会删除表中所有的行,并且不返回被删除的行。TRUNCATE操作无法回滚,因此一旦执行,数据将无法恢复。
效率和性能:
- TRUNCATE操作通常比DELETE操作更快,特别是在处理大型表时。TRUNCATE不会记录在日志中的每个删除操作,而是记录一次DDL操作,因此它的执行速度更快。
DELETE操作在数据库日志中会生成相应的日志记录,并且可能会触发相关的触发器和约束检查,因此相对而言会比TRUNCATE操作慢一些。
空间和索引:
- DELETE操作仅删除表中的数据行,但不释放与这些行相关的存储空间。这意味着如果表中存在大量被删除的行,可能会导致存储空间的碎片化。
TRUNCATE操作不仅会删除表中的数据行,还会释放与表相关的存储空间,这会导致数据文件的大小减小,并且存储空间被清空。
DELETE操作不会重置表的自增ID值,而TRUNCATE操作将重置表的自增ID值为初始值。
总结而言,DELETE和TRUNCATE都可以用于删除数据,但DELETE更加灵活和可控,可以根据需要指定删除条件,并且可以回滚操作。而TRUNCATE更适合用于快速地删除整个表的数据,并且执行速度更快、更有效,但无法回滚操作。选择使用哪个操作取决于具体的需求和情况。