[SQL系列] 从头开始学PostgreSQL 事务 锁 子查询

news2024/12/23 17:46:40

[SQL系列] 从头开始学PostgreSQL 索引 修改 视图_Edward.W的博客-CSDN博客https://blog.csdn.net/u013379032/article/details/131818865

事务

        事务是一系列逻辑相关的数据库操作,可以作为一个整体进行操作或者回滚。事务通常会包含一个序列的读或者写操作,通过提交给数据库管理系统,从而保证事务操作完成并且永久保存在数据库中。如果没有操作完成,则整个事务都会回滚,不会造成其他影响。

属性

        我们日常所说的ACID指的就是它的属性:

        1. 原子性 (Atomicity):事务中的所有操作在提交或回滚时都是作为一个整体进行的,不会中途停止或被中断。这意味着事务中的每个操作都会被完全执行,要么全部成功,要么全部失败。
        2. 一致性 (Consistency):事务在执行过程中必须保持数据一致性。这意味着在事务开始之前和结束之后,数据都必须处于一致状态。在事务执行过程中,如果数据发生了变化,那么这些变化必须在事务结束时被正确地应用到数据库中。
        3. 隔离性 (Isolation):事务的执行不能被其他事务干扰。这意味着在事务执行期间,其他事务无法访问事务所使用的数据或资源,从而避免了并发执行时的数据冲突和脏读等问题。
        4. 持久性 (Durability):事务的执行结果必须永久地保存在数据库中。这意味着即使在事务提交之后,事务的结果也不能被丢失或更改。

控制

        在PostgreSQL中,事务是通过Begin、Commit和Rollback命令用来创建,提交和回滚。EGIN 命令用于开始一个新的事务,COMMIT 命令用于提交当前的事务,ROLLBACK 命令用于回滚当前的事务。在事务期间,可以执行各种数据库操作,例如插入、更新、删除数据,查询数据等等。

通过begin  和   commit来标记一整个事务,中间是事务的具体操作命令。

BEGIN;  
SELECT id FROM users WHERE username = 'john';  
INSERT INTO orders (user_id, product, quantity, price)   
VALUES (1, 'apple', 2, 2.50);  
INSERT INTO orders (user_id, product, quantity, price)   
VALUES (1, 'orange', 1, 1.50);  
COMMIT;  

Commit命令可以把事务调用的更改保存到数据库中,也作为一整个事务的结尾。

而当我们提交了错误的事务的时候,可以通过rollback撤销尚未保存到数据库的事务命令。 

BEGIN;

DELETE FROM ORDERS WHERE quality = 1;

ROLLBACK;

        数据库中,锁的存在是为了保证数据库的一致性,在并发较高的数据库中,可以避免同时修改表产生的冲突。

一般来讲,有两种基本的锁:排它锁和共享锁。

如果数据对象加上了排他锁,那么其他的事务既不能读也不能修改它。

如果数据对象加上了共享锁,那么该对象可以被读,但是不能被修改。

还有更细粒度的行级锁:

1. 行共享锁,用于Select ... for update语句,允许多个并发事务访问同一行数据,但是只有一个事务可以更新该行数据。

2. 行独占锁,用于insert, update和delete语句,在事务完成前,其他事务无法访问该行数据

示例:

#共享锁
testdb=# begin;
BEGIN
testdb=*# lock table students in access share mode;
LOCK TABLE
testdb=*# commit;
COMMIT
#独占锁

testdb=# begin;
BEGIN
testdb=*# lock table students in access exclusive mode;
LOCK TABLE
testdb=*# commit;
COMMIT

锁必须加在事务中,不能随随便便的就写了lock,否决则会报错。

子查询

        子查询就是一种嵌套在另一个查询中的查询,反应会一个结果集,用于主查询中的条件或者数据比对。

        子查询还可以嵌套多层,用于实现复杂数据操作和数据过滤,从而提高查询效率和减少数据冗余。

举个例子:



#原始表格
testdb=# select * from engineer;
 id | name  | age | gender |    address    |     created_at      
----+-------+-----+--------+---------------+---------------------
  1 | John  |  30 | M      | New York      | 2023-02-18 10:00:00
  2 | Mary  |  25 | F      | Los Angeles   | 2023-02-18 10:00:00
  3 | Peter |  35 | M      | Chicago       | 2023-02-18 10:00:00
  4 | Jane  |  28 | F      | San Francisco | 2023-02-18 10:00:00
  5 | Bob   |  40 | M      | Boston        | 2023-02-18 10:00:00
  6 |       |     | F      | Washington DC | 2023-02-18 10:00:00
  7 |       |     | M      | Atlanta       | 2023-02-18 10:00:00
  8 |       |     | F      | Miami         | 2023-02-18 10:00:00
  9 |       |     | M      | Philadelphia  | 2023-02-18 10:00:00
 10 |       |     | F      | Dallas        | 2023-02-18 10:00:00
(10 rows)

#经过了子查询的表格,子查询筛选了所有gender是'M'的,主查询将它都输出来
testdb=# select * from engineer where id in (select id from engineer where gender = 'M');
 id | name  | age | gender |   address    |     created_at      
----+-------+-----+--------+--------------+---------------------
  1 | John  |  30 | M      | New York     | 2023-02-18 10:00:00
  3 | Peter |  35 | M      | Chicago      | 2023-02-18 10:00:00
  5 | Bob   |  40 | M      | Boston       | 2023-02-18 10:00:00
  7 |       |     | M      | Atlanta      | 2023-02-18 10:00:00
  9 |       |     | M      | Philadelphia | 2023-02-18 10:00:00
(5 rows)


#我们再来一个
#原始表格
testdb=# select * from students;
 id |  name  | age | gender | class_id 
----+--------+-----+--------+----------
  1 | 张三   |  18 | 男     |        1
  2 | 李四   |  19 | 女     |        1
  3 | 王五   |  20 | 男     |        2
  4 | 赵六   |  18 | 女     |        2
  5 | 陈七   |  19 | 男     |        3
  6 | 孙八   |  20 | 女     |        3
  7 | 周九   |  18 | 男     |        4
  8 | 吴十   |  19 | 女     |        4
  9 | 郑十一 |  20 | 男     |        5
 10 | 王十二 |  18 | 女     |        5
 11 | 何一   |  23 | 女     |        5
 12 | 和二   |  32 | 男     |        5
(12 rows)

#作为列选项
testdb=# select name, (select count(*) from students where students.age > 20) as male_count from students;
  name  | male_count 
--------+------------
 张三   |          2
 李四   |          2
 王五   |          2
 赵六   |          2
 陈七   |          2
 孙八   |          2
 周九   |          2
 吴十   |          2
 郑十一 |          2
 王十二 |          2
 何一   |          2
 和二   |          2
(12 rows)

当然,除了select,也可以用于delete和Update,总之,子查询,实际上就是一种嵌套查询方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

No4: Python脚本的交互式运用

No4: Python脚本的交互式运用 1、 先安装了Python和环境变量设置 2、编写Pthon脚本 3、在脚本所在目录位置下,Python 脚本;

Nginx系列之 一 负载均衡

目录 一、Nginx概述 1.1 负载均衡概述 1.2 负载均衡的作用 1.3 四/七层负载均衡 1.3.1 网络模型简介 1.3.2 四层和七层负载均衡对比 1.3.3 Nginx七层负载均衡实现 1.4 Nginx负载均衡配置 1.5 Nginx负载均衡状态 1.6 Nginx负载均衡策略 二、负载均衡实战 2.1 测试服…

论文笔记--Won’t Get Fooled Again: Answering Questions with False Premises

论文笔记--Won’t Get Fooled Again: Answering Questions with False Premises 1. 文章简介2. 文章概括3 文章重点技术3.1 大模型面对FPQs的表现3.2 False QAs数据集3.3 训练和评估 4. 文章亮点5. 原文传送门 1. 文章简介 标题:Won’t Get Fooled Again: Answerin…

LLMs之LLaMA2:LLaMA2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途)之详细攻略

LLMs之LLaMA2:LLaMA2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途)之详细攻略 导读:2023年7月18日,Meta重磅发布Llama 2!这是一组预训练和微调的大型语言模型(LLM),规模从70亿…

(三)springboot实战——web新特性之函数式实现

前言 本节内容我们主要介绍一下web访问的另一种形式,通过函数式web实现一个restful风格的http请求案例。函数式web是spring5.2之后的一个新特性,可以通过函数去定义web请求的处理流程,使得代码更为简洁,耦合性也降低了。 正文 …

在vue3中配置ByteMD掘金同款markdown编辑器

最近因为想要一个富文本编辑器集合到项目中,在查找网上很多资料后,选择了ByteMD 编辑器,ByteMD 编辑器是字节跳动的掘金团队所开源的一个编辑器组件,还挺好用的,那如果要在vue3项目中配置ByteMD编辑器要如何配置呢&…

【YOLO】关闭控制台推理日志

问题 每次推理时,控制台都会打一条日志 消除方法 外部库里找到\site-packages\ultralytics\engine\predictor.py 将代码的282、283、292、293,这四行注释掉(v5和v8一样) 也可以搜关键词# Print time (inference-only)可以定位代…

基于PHP+ vue2 + element +mysql自主研发的医院不良事件上报系统

医院不良事件上报管理系统源码 不良事件上报是为了响应卫生部下发的等级医院评审细则中第三章第9条规定:医院要有主动报告医疗安全(不良)事件的制度与工作流程。由医疗机构医院或医疗机构报告医疗安全不良事件信息,利用报告进行研…

WEB安全测试通常要考虑的测试点

1、问题:没有被验证的输入 测试方法: 数据类型(字符串,整型,实数,等) 允许的字符集 最小和最大的长度 是否允许空输入 参数是否是必须的 重复是否允许 数值范围 特定的值(枚举型&a…

基于UDP的可靠传输,文件+目录(C++,Qt)

一、基础知识 UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留…

【Tomcat】无法将位于-的资源添加到Web应用程序-的缓存中,因为在清除过期缓存条目后可用空间仍不足 - 请考虑增加缓存的最大空间

1、问题 org.apache.catalina.webresources.Cache.getResource Unable to add the resource at [xxx] to the cache for web application [/xxx] because there was insufficient free space available after evicting expired cache entries - consider increasing the maxim…

为Android构建现代应用——设计原则

为Android构建现代应用——设计原则 - 掘金 state”是声明性观点的核心 在通过Compose或SwiftUI等框架设计声明性视图时,我们必须明确的第一个范式是State(状态)。UI组件结合了它的图形表示(View)和它的State(状态)。UI组件中发生变化的任何属性或数据都可以…

Kotlin~Observer观察者模式

概念 定义一对多的依赖关系,让多个观察者同时监听一个主题对象。 角色介绍 Subject:主题,也称被观察者,它是具有状态的对象维护着一个观察者列表。提供添加、删除和通知观察者的方法。ConcreteSubject:具体主题&…

mfc140.dll丢失的解决方法(最新解决方法)

一:mfc140.dll的作用: mfc140.dll的主要作用是提供了(简称MFC)的函数和资源,它是用于构建Windows应用程序的一组C类库。MFC是微软开发环境中提供的一个工具集,它封装了Windows操作系统的底层API&#xff0…

2.多线程-初阶(中)

文章目录 4. 多线程带来的的风险-线程安全 (重点)4.1 观察线程不安全4.2 线程安全的概念4.3 线程不安全的原因4.3.1原子性4.3.2可见性4.3.3代码顺序性 4.4 解决之前的线程不安全问题 5. synchronized[ˈsɪŋkrənaɪzd] 关键字-监视器锁monitor lock5.1 synchronized 的特性5.…

【限流】4 种常见的限流实现方案

在微服务应用中,考虑到技术栈的组合,团队人员的开发水平,以及易维护性等因素,一个比较通用的做法是,利用 AOP 技术 自定义注解实现 对特定的方法或接口进行限流。 下面基于这个思路来分别介绍下几种常用的限流方案的…

OceanBase 压测时为什么冻结阈值在变化?

本文从源码角度分析了 OceanBase 压测中冻结阈值动态变化的原因,并给出运维建议。 作者:张乾 外星人2号,兼任五位喵星人的铲屎官。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转…

Redis两种持久化机制RDB和AOF详解(面试常问,工作常用)

redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失。幸好Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)。 在这里假设你已经了解了redis的基础…

微信小程序上,实现图片右上角数字显示

微信小程序上,实现图片右上角数字显示 直接上代码: 样式代码index.wxss如下: .circle_rednum {position: absolute;color: white;font-size: 13px;background-color: #EC2F43;width: 23px;height: 23px;line-height: 23px;left: 80%;top: …

RuntimeError: DataLoader worker (pid 2105929) is killed by signal: Killed.

PyTorch DataLoader num_workers Test - 加快速度 可以利用PyTorch DataLoader类的多进程功能来加快神经网络训练过程。 加快训练进程 为了加快训练过程,我们将利用DataLoader类的num_workers可选属性。 num_workers属性告诉DataLoader实例要使用多少个子进程进…