首先复习了一下乐观锁和悲观锁

乐观锁和悲观锁

乐观锁

乐观锁指的是我们在对于修改操作,我们不会直接把整个过程加个锁,而是在更新数据的时候,判断一下当前的数据和之前获取的数据是否相同,如果相同就进行更新操作,如果不相同就可以重试或者异常

悲观锁:

悲观锁指的是我们就需要把整个操作过程加个锁,任何一个线程想要执行必须要先获得锁,这样能够确保线程串行执行。

乐观锁和悲观锁在应用上的区别

乐观锁适合应用在更新数据上面,而悲观锁则适合插入数据

其次复习了一下Redis在解决分布式锁问题上面的优劣势

Redis来解决分布式锁问题

首先为什么会产生分布式问题?

因为我们有时候会部署很多tomcat,tomcat都有自己的jvm,所以两个不同的tomca的线程获取的锁不会是一个锁,那么我们的synchronized锁相当于失效了,所以我们就不能使用synchronized来解决这个问题

解决方案有三种:

  • 使用Redis的Set nx ex操作来解决
  • 使用Zookeeeper来解决分布式锁问题
  • 使用mysql来解决,因为mysql本身就是具有锁机制,但是因为mysql的本身的性能一般,所以很少用来解决分布锁问题。

我今天学习使用Redis的Set nx ex操作来解决分布式锁的问题

  • nx的意思是not exists,指的是当且仅当 key 不存在时,才设置值。若 key 已存在,操作失败。
  • ex指的是expire,指的是锁有过期时间,这个操作是为了防止死锁的产生

Redis的Set nx ex操作必须要搭配Lua脚本来进行使用为了保证操作的原子性

        获取锁必须用 SET NX EX 原子操作,否则可能出现死锁。

        释放锁必须用 Lua 脚本,确保判断和删除的原子性。、

Redis的Set nx ex操作来解决分布式锁的优势和劣势:

  • 优势是代码实现简单,且基于redis的单线程特性,操作高效,且支持redis集群,扩展性更高。
  • 劣势是在主从架构下,主节点挂掉可能导致锁丢失(需使用 RedLock 解决)。且锁续期复杂:若业务执行时间不确定,需实现锁自动续期(如 Redisson 的看门狗机制)。

Sql题目练习

SQL206

题目链接:sql206题目链接

题目总结:

通过这个题目我复习了group by子句的使用,group by的使用常常配合聚合函数使用,使用GROUP BY子句可以将行分组并计算每个组的聚合函数(如COUNT、SUM、AVG等)。

举一个例子来说明group by的作用

当我们有一个名为orders的表,其中包含订单信息,我们想要计算每个顾客的订单总金额和订单数量,可以使用GROUP BY子句进行分组。以下是一个示例:

假设orders表如下:

order_id customer_id order_amount
1 101 50
2 102 75
3 101 100
4 103 80
5 101 60

我们可以使用以下SQL查询来计算每个顾客的订单总金额和订单数量:

SELECT customer_id, COUNT(order_id) AS num_orders, SUM(order_amount) AS total_amount
FROM orders GROUP BY customer_id;

执行上面的查询后,将得到以下结果:

customer_id num_orders total_amount
101 3 210
102 1 75
103 1 80

Q:那么group by子句可以不搭配聚合函数进行使用吗?

答案是可以的,如果使用GROUP BY子句但不添加聚合函数,则查询将返回每个组的唯一行。换句话说,将根据指定的列对数据进行分组,并且每个组将包含具有唯一值的行。例如,下面是一个不使用聚合函数的示例:(表还是上面那张orders表)

我们可以使用以下SQL查询来根据customer_id对订单进行分组,但不使用聚合函数:

SELECT customer_id, order_id, order_amount
FROM orders GROUP BY customer_id;

执行上面的查询后,将得到以下结果:

customer_id order_id order_amount
101 1 50
102 2 75
103 4 80

由上面我们可以看到表格就遗漏了数据,所以大多数情况下group by子句还是搭配聚合函数进行使用比较好。

其次通过这道题我还复习了count(字段)和coun(1)还有count(*)之间的区别

COUNT(1) 和 COUNT(*) 均返回表的总行数(包含所有记录)。

  1. COUNT(字段):COUNT函数后面可以指定一个字段名,用于计算该字段中非NULL值的行数。例如,COUNT(customer_id)将计算customer_id字段中非NULL值的行数。

  2. COUNT(1):COUNT函数中也可以使用1作为参数,表示计算所有的行数。COUNT(1)的作用是计算行数,不考虑字段的值。实际上,COUNT(1)会对每一行进行计数,因为每一行都会被表示为1。

  3. COUNT(*):COUNT(*)用于计算所有行的行数,包括包含NULL值的行和重复行。COUNT(*)通常用于计算表的总行数。

提交代码

select emp_no, t
from(
select emp_no,count(*)as t
from salaries
group by emp_no
)s
where t>15

 

 posted on 2025-06-23 00:09  熙玺  阅读(10)  评论(0)    收藏  举报

Shu-How Zの小窝

Loading...