1分组操作
用途:主要是用来做统计的
实现过程:把相同属性的事物放在一起,作为一组,使用的关键字为GROUP BY
例:统计每种分类下有多少商品
SELECT category_name,COUNT(*) FROM `product` GROUP BY category_name
如果需要添加过滤条件则使用关键词:HAVING
统计数量大于2的商品
SELECT category_name,COUNT(*) FROM `product` GROUP BY category_name HAVING COUNT(*)>2
如果需要排序则使用关键词:ORDER BY
SELECT category_name,COUNT(*) FROM `product` GROUP BY category_name HAVING COUNT(*)>2 ORDER BY COUNT(*)
2、排序
语法select * from 表名 order by 列1 asc|desc,列2 asc|desc,.......;,可以是一个排序条件,也可以是多个排序条件,多个排序条件是,按顺序在上一个基础上进行排序
例:
SELECT * FROM `product` ORDER BY price DESC,pid DESC
3、分页
对数据进行进行分页使用关键词limit
语法:limit 起始位置,长度
SELECT * FROM `product` ORDER BY price DESC,pid DESC limit 1,2
4查询
4.1 条件查询
select * from 表名 where 条件
SELECT * FROM `product` WHERE pid=1
4.2模糊查询
使用关键词like ,%任意字符任意多个;_一个字符
SELECT * FROM `product` WHERE pname LIKE '%想%';
SELECT * FROM `product` WHERE pname LIKE '_想%';
4.3范围查询
in 在一个非连续的范围内 between在一个连续的范围内
SELECT * FROM `product` WHERE pid in (1,3);
SELECT * FROM `product` WHERE pid BETWEEN 1 AND 3;
5、事务
事务是一个由一条或多条SQL组成的一个整体,事务中的操作要么全部成功,要么全部失败。
使用事务是为了防止数据出现混乱,如转账,如果不使用事务会出现错误
UPDATE `product` SET price = price+500 WHERE pid=1;
d
UPDATE `product` SET price = price-500 WHERE pid=3;
事务操作
手动提交事务:
1开启事务 START TRANSACTION 或者 BEGIN
2提交事务 COMMIT;
3回滚 ROLLBACK;
自动提交:
默认自动提交
查看是否自动提交,进入到当前数据库执行
SHOW VARIABLES LIKE 'autocommit';
修改
SET @@autocommit=off;
5.1事务的四大特性 ACID
5.1.1原子性
每个事务都是一个整体,不可再拆分,事务中所有的 SQL 语句要么都执行成功, 要么都失败。
5.1.2一致性
事务在执行前数据库的状态与执行后数据库的状态保持一致。如:转账前2个人的 总金额是 2000,转账后 2 个人总金额也是 2000.
5.1.3隔离性
事务与事务之间不应该相互影响,执行时保持隔离的状态.
5.1.4持久性
一旦事务执行成功,对数据库的修改是持久的。就算关机,数据也是要保存下来的
6、数据库的并发
一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库. 数据库的相同数据可能
被多个事务同时访问,如果不采取隔离措施,就会导致各种问题, 破坏数据的完整性
6.1并发访问会产生的问题
事务在操作时的理想状态: 所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问
同一个 数据。可能引发并发访问的问题
6.1.1脏读
一个事务读取到了另一个事务中尚未提交的数据
6.1.2不可重复读
一个事务中两次读取的数据内容不一致, 要求的是在一个事务中多次读取时数据是一致的. 这是进行 update 操作时引发的问题
6.1.3幻读
一个事务中,某一次的 select 操作得到的结果所表征的数据状态, 无法支撑后续的业务操作. 查询得到的数据状态不准确,导致幻读
6.2数据库的隔离级别
6.2.1查看隔离级别
mysql80查看使用select @@transaction_isolation;
mysql8以前的查看使用select @@tx_isolation;
6.2.2修改隔离级别
设置事务隔离级别,需要退出 MySQL 再重新登录才能看到隔离级别的变化
set global transaction isolation level 级别名称;
read uncommitted 读未提交
read committed 读已提交
repeatable read 可重复读
serializable 串行化
set global transaction isolation level read uncommitted;
6.3演示
6.3.1脏读
1、设置隔离级别
set global transaction isolation level read uncommitted;
2、打开两个窗口选择数据库
use lianxi01
3、窗口A执行语句查询当前的数值
SELECT * FROM `product` WHERE pid =1;
窗口B执行开启事务语句
begin;
然后执行修改
UPDATE product SET price = price +5000;
4、窗口A在执行查询语句,发现数值已经改变
SELECT * FROM `product` WHERE pid =1;
5、窗口B执行回滚
ROLLBACK;
6、A在进行查询发现数值有变回去了。
7、问题场景
脏读非常危险的,比如张三向李四购买商品,张三开启事务,向李四账号转入 500 块,然后打电话给李四说钱 已经转了。李四一查询钱到账了,发货给张三。张三收到货后回滚事务,李四的再查看钱没了。
6.3.2不可重复读
1、打开两个 窗口A 和 窗口B,选择数据库后 开启事务
2、B 窗口开启事务后, 先进行一次数据查询
3、 在 A 窗口开启事务后进行数据更新
4、 B 窗口再次查询数据,发现两次查的数据不一致
5、问题场景
比如银行程序需要将查询结果分别输出到电脑屏幕和发短信给客 户,结果在一个事务中针对不同的输出目的地进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作 人员就不知道以哪个为准了
6.3.3幻读
幻读: select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
1、打开 A B 窗口, 选择数据库 开启事务
2、A 窗口 先执行一次查询操作
3、B 窗口 插入一条数据 提交事务
4、 A 窗口执行 插入操作, 发现报错. 出现幻读
如果一个事务,使用了SERIALIZABLE——可串行化隔离级别时,在这个事务没有被提交之前 , 其他的线程,只能等到当前操作完成之后,才能进行操作,这样会非常耗时,而且,影响数据库的性能,数据库不会使用这种隔离级别。
serializable 串行化可以彻底解决幻读,但是 事务只能排队执行,严重影响效率,数据库不会使用这种隔离级别。