Rumah > Artikel > pangkalan data > 数据库之子查询和事务隔离级别
数据库大的知识点,特此补上。看的还是《漫画数据库》。 一、查询 如果要从一个数据库里面检索出某一字段为最大的数据项,那用什么方法呢?其实用子查询就可以查到。 1)子查询是查询里面再嵌套查询。 people表: 如果我要查询年龄最大的那一行数据项。就可以
数据库大的知识点,特此补上。看的还是《漫画数据库》。
一、查询
如果要从一个数据库里面检索出某一字段为最大的数据项,那用什么方法呢?——其实用子查询就可以查到。
1)子查询是查询里面再嵌套查询。
people表:
如果我要查询年龄最大的那一行数据项。就可以使用子查询。
select * from people where age = (select max(age) from people);选出people里面的最大年龄,再选出年龄等于最大值的数据。
当然,还有另外一种方法。
select * from people order by age desc limit 1;通过从大到小的排序,并且限制数据为一条,那么就是最大的了。当然,有两条数据都是最大,那么这条语句就不完美了。
2)相关子查询
子查询内部嵌套的表格其实可以使用外部指定的表格,为相关子查询。这里说的不是外部和内部的表格一定是不同的。看例子。
假如现在选出年龄大于本国平均年龄的人,单单用子查询是查不了的,因为我们需要每条数据的国家都和平均年龄的国家对应。
select * from people p where age>(select avg(age) from people where count ry = p.country);选出平均年龄的时候,如果没有where country = p.country那么选出来的只是大于全部人的平均年龄的数据。
但是有了之后,假如选到country为a的数据,那就会根据a国家的平均年龄进行比较,最终得到结果。
灵活运用子查询功能是很强大的。设定隔离级别后的现象。
先解释三个现象:
脏读:dirty read,事务1提交之前,事务2读取了1中的数据,1一旦回滚,2读取了不存在的数据的现象。
我本金10元,往银行存了10元,后面没存了,但是银行那边读多10元,并且按20元处理。
不可重复读:non-repeatable read,事务1读取时,事务2更新并提交,事务1再读取,发现前后数据不同。
银行查账单,发现你有10元,然后你取了10元出来,银行再查,发现余额为0。前后不同。
虚度(幻读):phatom,事务1检索多行数据,事务2插入符合检索条件的新数据,事务1第二次检索发现前后数据不同。
银行查询你的消费清单,你又跑去消费了,然后后面再查发现新消费的账单怎么不在第一次的查询里面,如幻影般消失。
read uncommited,读未提交,以上三种现象都可能会发生。
read commited,读提交,防止脏读,脏读的问题解决就是提交完成的数据才给你读,不然一旦回滚,读出来就是错的。
repeateable read,重复读,防止脏读和不可重复读,不可重复读确实是发生在事务提交之后,问题在于读取的时候又有事务进行更改,所以问题解决是,一旦读取数据,就不让你在中途进行更新(MySQL默认级别)。
serializable,序列化,防止三种现象,幻读问题是,你事务进行检索数据之后,有人插入新的数据,后面再检索发现多了一条,好比银行小姐明明就看你消费100元,后面你又刷卡1000,后面查出来的总消费是1100,这是银行小姐就慌张了。
解决问题所在就是读取数据时还禁止其他事务进行插入或者删除。
这样看来,其实事务的隔离机制就是在控制事务后其他事务不能进行的操作,隔离级别越高,条件就越多,代价越大,但是也不会出现任何的三种现象。
4)悲观锁和乐观锁
悲观锁:给加载的数据加锁,不让其他事务更新和加载,这样,脏读和不可重复读都不会出现,虚读还是有的,因为还是可以插入或者删除数据。
乐观锁:并不会像悲观那样锁死,基于数据版本的记录,更新最后的更新,这样的话,其实不可重复读的问题还是存在的。
根据不同的数据库设计和性能要求进行所需要的隔离级别,才是最恰当的。