Oracle 数据库执行增删改查命令的原理与过程
摘要: 本文深入探讨当向 Oracle 数据库发送一个增删改查(CRUD)命令时,数据库内部的执行机制与详细过程。从用户发起命令开始,逐步剖析命令在 Oracle 数据库体系结构各组件中的流转、解析、优化以及执行路径,涵盖了 SQL 语句解析、共享池的作用、查询优化器的工作原理、数据存储与读取机制以及事务处理等多方面内容,旨在为数据库开发者、管理员以及相关技术爱好者全面呈现 Oracle 数据库处理 CRUD 操作背后的复杂而精妙的技术原理。
一、引言
Oracle 数据库作为全球广泛应用的关系型数据库管理系统,以其强大的功能、卓越的性能和高度的可靠性著称。在企业级应用中,大量的业务数据操作都依赖于对 Oracle 数据库的增删改查操作。理解当发送一个增删改查命令给 Oracle 数据库时,数据库是如何执行该命令的,对于优化数据库性能、确保数据完整性和一致性以及进行高效的数据库应用开发具有极为重要的意义。这一过程涉及到数据库体系结构的多个层面以及一系列复杂的技术组件协同工作,下面将详细展开介绍。
二、用户发起 CRUD 命令
(一)客户端与数据库连接
当用户或应用程序需要对 Oracle 数据库执行增删改查操作时,首先要建立与数据库服务器的连接。这一连接过程通常通过 Oracle 提供的客户端驱动程序(如 JDBC、OCI 等)来实现。客户端驱动程序负责处理与数据库服务器的网络通信协议,将用户在应用程序中编写的 SQL 语句(增删改查命令)发送到数据库服务器端。例如,在一个 Java 应用程序中使用 JDBC 连接 Oracle 数据库时,需要加载 JDBC 驱动,设置数据库连接参数(如主机地址、端口号、数据库实例名、用户名和密码等),然后通过DriverManager.getConnection()
方法建立连接对象,后续的 SQL 操作都将基于这个连接对象进行。
(二)SQL 语句发送
一旦连接建立成功,用户编写的增删改查 SQL 语句便被发送到数据库服务器。以一个简单的查询语句为例,如SELECT * FROM employees WHERE department_id = 10;
,这条语句旨在从名为employees
的表中检索出部门编号为10
的所有员工记录。SQL 语句作为文本形式的指令,在网络传输后到达数据库服务器的监听进程。Oracle 数据库的监听进程负责接收来自客户端的连接请求和 SQL 语句,它在数据库服务器的指定端口(默认是 1521)上监听,一旦接收到客户端的请求,便将 SQL 语句传递给数据库实例进行后续处理。
三、SQL 语句解析
(一)语法检查
在数据库实例接收到 SQL 语句后,首先进入解析阶段的语法检查环节。Oracle 数据库的解析器会对 SQL 语句进行词法和语法分析,类似于编译器对程序代码的检查。它会检查 SQL 语句是否符合 Oracle SQL 语言的语法规则,例如关键字是否正确使用、表名和列名是否合法、运算符是否匹配等。如果 SQL 语句存在语法错误,如拼写错误的关键字(如将SELECT
写成SELET
)或不匹配的括号,解析器会立即检测到并返回错误信息给客户端,此时数据库不会执行该命令,整个操作终止。例如,对于语句SELET * FROM employees;
,解析器会识别出SELET
是错误的关键字,并向客户端报告语法错误。
(二)语义分析
在语法检查通过后,进入语义分析阶段。这一过程主要检查 SQL 语句在数据库对象层面的语义正确性。解析器会验证语句中涉及的表、列、视图、函数等数据库对象是否存在于数据库中,以及用户是否具有对这些对象执行相应操作的权限。例如,如果用户发送SELECT salary FROM non_existent_table;
,由于表non_existent_table
不存在,语义分析阶段会检测到这个问题并返回错误信息。同时,如果用户没有对employees
表进行SELECT
操作的权限,即使语法正确,语义分析也会阻止该语句的执行并报告权限不足的错误。
(三)共享池与游标共享
经过语法和语义分析后,如果 SQL 语句合法且用户具有相应权限,Oracle 数据库会考虑将该语句放入共享池中。共享池是 Oracle 数据库系统全局区(SGA)中的一个重要内存区域,用于缓存 SQL 语句、PL/SQL 代码块以及它们的执行计划等信息。当一条 SQL 语句进入共享池时,数据库会检查是否已经存在相同文本的 SQL 语句。如果存在,数据库会尝试重用已有的执行计划,这一过程称为游标共享。例如,假设有多个用户同时执行相同的查询语句SELECT * FROM employees WHERE department_id = 10;
,第一个用户执行该语句时,数据库会生成一个执行计划并将其与该 SQL 语句一起缓存到共享池中。当后续用户执行相同语句时,数据库直接使用共享池中已有的执行计划,而无需重新生成,从而大大提高了执行效率,减少了资源消耗。
四、查询优化器的工作原理
(一)生成执行计划
如果 SQL 语句在共享池中没有找到可重用的执行计划,或者由于某些原因(如数据库对象统计信息更新)需要重新生成执行计划,查询优化器就会介入。查询优化器的主要任务是为 SQL 语句生成一个最优的执行计划,该计划描述了数据库如何从存储介质(如磁盘)中读取数据、如何对数据进行连接、过滤、排序等操作以得到最终的结果集。对于一个查询语句,优化器会考虑多种可能的执行路径,例如对于连接操作,可以选择不同的连接算法(如嵌套循环连接、哈希连接、排序 - 合并连接);对于数据访问,可以选择全表扫描、索引扫描、索引快速全扫描等方式。以SELECT * FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE d.location_id = 100;
为例,优化器需要决定先访问哪个表、如何连接这两个表以及是否使用索引等。
(二)基于成本的优化
Oracle 数据库的查询优化器主要采用基于成本的优化方法。它会根据数据库对象的统计信息(如表的行数、列的基数、索引的选择性等)以及系统参数(如 CPU 速度、磁盘 I/O 速度等)来估算每种执行计划的成本。成本通常以一种抽象的单位来衡量,包括 CPU 成本和 I/O 成本等。优化器会比较不同执行计划的成本,选择成本最低的执行计划作为最终的执行方案。例如,如果employees
表有大量数据且department_id
列上有合适的索引,而departments
表数据量相对较小且location_id
列没有索引,优化器可能会选择先扫描departments
表,然后通过索引访问employees
表进行连接操作,以减少整体的 I/O 和 CPU 消耗。
(三)统计信息的作用
数据库对象的统计信息对于查询优化器生成准确的执行计划至关重要。统计信息包括表的行数、块数、平均行长,列的最小值、最大值、不同值的数量(基数),索引的高度、叶子节点数等。Oracle 数据库会定期自动收集或在用户手动执行DBMS_STATS
包中的相关过程时收集这些统计信息。如果统计信息不准确或过时,可能会导致优化器生成非最优的执行计划。例如,如果一个表的数据量在近期大幅增加,但统计信息没有及时更新,优化器可能会基于旧的统计信息选择不合适的执行策略,如错误地估计全表扫描的成本低于索引扫描,从而导致查询性能下降。
五、数据存储与读取机制
(一)数据存储结构
Oracle 数据库将数据存储在数据块(Data Block)中,数据块是数据库存储的最小逻辑单元,通常大小为 2KB、4KB、8KB 或 16KB 等。多个数据块组成一个数据区间(Extent),多个数据区间组成一个段(Segment)。例如,一个表的数据存储在一个或多个段中,索引也有自己独立的段。数据块中包含了数据行、空闲空间以及一些管理信息,如块头(包含块的类型、地址、事务槽等信息)和行目录(记录数据行在块中的位置)。当执行增删改查操作时,数据库需要根据数据的存储结构来定位和操作数据。
(二)数据读取方式
- 全表扫描
在某些情况下,如查询语句没有合适的索引或者优化器认为全表扫描的成本更低时,数据库会执行全表扫描操作。全表扫描意味着数据库会顺序读取表所在段的所有数据块,从第一个数据块开始,逐块读取直到最后一个数据块,以查找满足查询条件的数据行。例如,对于查询SELECT * FROM large_table;
,如果large_table
没有合适的索引且数据量不是特别巨大,优化器可能选择全表扫描。在全表扫描过程中,数据库会利用操作系统的预读功能,提前将可能需要的数据块读入内存缓冲区,以提高读取效率。 - 索引扫描
当 SQL 语句中的查询条件涉及到有索引的列时,数据库可能会选择索引扫描方式。索引扫描分为多种类型,如索引唯一扫描(当查询条件能唯一确定一行数据时)、索引范围扫描(查询条件是一个范围,如WHERE salary > 5000
)、索引全扫描(查询需要获取索引中的所有列数据)等。以索引范围扫描为例,数据库会先读取索引树结构,根据索引列的值定位到满足条件的数据行在表中的物理位置(通过索引中的 ROWID 信息),然后再读取相应的数据行。例如,对于查询SELECT * FROM employees WHERE hire_date BETWEEN '01-JAN-2020' AND '31-DEC-2020';
,如果hire_date
列上有索引,数据库会先在索引中查找符合日期范围的索引条目,然后根据 ROWID 获取对应的员工数据行。
六、事务处理
(一)事务开始
在 Oracle 数据库中,增删改操作都在事务的环境下进行。当执行一个增删改语句时,数据库会自动开启一个事务。事务是一组数据库操作的逻辑单元,这些操作要么全部成功执行并提交,要么全部失败回滚,以确保数据的一致性和完整性。例如,在一个银行转账的场景中,从一个账户转出资金和向另一个账户转入资金这两个操作就应该在一个事务中进行,只有当两个操作都成功时,事务才提交;如果其中一个操作失败,整个事务就会回滚,两个账户的余额都不会发生变化。
(二)数据修改与日志记录
在事务执行过程中,对于增删改操作,数据库会先在数据缓冲区(Buffer Cache)中对数据进行修改,而不是直接修改磁盘上的数据。同时,数据库会将修改操作记录在重做日志缓冲区(Redo Log Buffer)中。重做日志记录了对数据的所有修改操作,以便在数据库故障恢复时能够重现这些操作。例如,当执行INSERT INTO accounts (account_number, balance) VALUES ('123456', 1000);
语句时,数据库会在数据缓冲区中为新插入的账户记录分配空间并写入数据,同时在重做日志缓冲区中记录插入操作的详细信息,包括插入的数据值、表名、操作时间等。
(三)事务提交与回滚
当事务中的所有操作都成功完成后,用户可以选择提交事务。提交事务时,数据库会将数据缓冲区中修改后的脏数据块写入磁盘(通过数据库写进程 DBWR),同时将重做日志缓冲区中的日志记录写入重做日志文件(通过日志写进程 LGWR)。这样,即使在提交事务后数据库发生故障,也可以通过重做日志文件恢复已提交的事务。如果在事务执行过程中发生错误或者用户决定取消事务,数据库会执行回滚操作。回滚操作会根据重做日志中的信息,撤销事务中对数据的所有修改,将数据恢复到事务开始前的状态。例如,如果在转账事务中,向目标账户转入资金成功,但从源账户转出资金时发生错误(如源账户余额不足),整个事务会回滚,目标账户的余额也会恢复到原来的值。
七、执行结果返回
当数据库完成增删改查命令的执行后,会将执行结果返回给客户端。对于查询操作,结果集将包含满足查询条件的数据行和列信息,这些数据会按照客户端请求的格式(如表格形式、XML 格式等)进行封装并通过网络传输回客户端。对于增删改操作,数据库会返回操作影响的行数等相关信息,以告知用户操作的执行情况。例如,对于UPDATE employees SET salary = salary * 1.1 WHERE department_id = 20;
语句,数据库执行后会返回更新的员工记录行数,以便客户端应用程序进行后续处理,如显示更新成功的提示信息并告知用户有多少员工的工资得到了调整。
八、总结
当向 Oracle 数据库发送一个增删改查命令时,数据库内部经历了一个复杂而严谨的执行过程。从用户发起命令、SQL 语句解析、查询优化器生成执行计划、数据存储与读取、事务处理到最终结果返回,每一个环节都紧密相连且相互影响。深入理解这一过程有助于数据库开发人员编写更高效的 SQL 语句,数据库管理员进行性能优化和故障排查,以及企业更好地利用 Oracle 数据库管理和处理大量的业务数据,确保数据操作的准确性、高效性和可靠性,在企业信息化建设和数据管理领域具有极为重要的意义。随着数据库技术的不断发展,Oracle 数据库也在持续改进其执行机制,如引入更智能的优化算法、更高效的数据存储结构和处理方式等,以适应日益增长的数据处理需求和复杂多变的业务场景。
相关文章:
Oracle 数据库执行增删改查命令的原理与过程
摘要: 本文深入探讨当向 Oracle 数据库发送一个增删改查(CRUD)命令时,数据库内部的执行机制与详细过程。从用户发起命令开始,逐步剖析命令在 Oracle 数据库体系结构各组件中的流转、解析、优化以及执行路径,…...
HBase难点
查询优化 一次Scan会返回大量数据,客户端向HBase发送一次Scan请求,实际上并不会将所有数据加载到本地,而是通过多次RPC请求进行加载,防止客户端OOM。禁止缓存优化:批量读取数据时会全表扫描一次业务表,这种…...

Y20030023 PHP+thinkphp+MYSQL+LW+基于PHP的健身房管理系统的设计与实现 源代码 配置 初稿
基于PHP的健身房管理系统 1.项目摘要2. 系统开发的背景及意义3.项目功能4.界面展示5.源码获取 1.项目摘要 近年来,随着社会发展和科技进步,人们越来越重视健康养生并关注电子商务对日常交流方式的影响。随着健身行业消费人群的增加,竞争变得…...

mongodb下载与使用
下载地址: Install MongoDB Community Kubernetes Operator | MongoDB 1、安装MongoDB (5.0.30) 将压缩包移动到C:\Program Files 下,然后解压创建C:\data\db目录,mongodb 会将数据默认保存在这个文件夹以mongodb 中 bin目录作为工作目录&…...

【Linux基础】Linux基本指令
目录 1、pwd 指令 2、clear 指令 3、ls 指令 1、ls 显示当前路径下的文件或者目录名称 2、ls -l 显示当前路径下的文件或者目录的更详细的属性信息 3、ls -a :显示所有文件,包括隐藏文件 4、ls -d 将目录像文件一样显示,而不是显示其…...
【RISC-V CPU debug 专栏 3 -- Debugging RISC-V Cores】
文章目录 RISC-V 调试规范开源与多样性挑战调试规范的重要性外部调试支持的主要组件调试功能Lauterbach 的贡献RISC-V 调试规范 调试 RISC-V 内核涉及许多独特的挑战,这是由 RISC-V 的开源特性和多样化的生态系统所决定的。为了避免专有调试接口的泛滥,RISC-V 基金会内的工作…...

思科实现网络地址转换(NAT)和访问控制列表(ACL)和动态路由配置并且区分静态路由和动态路由配置。
实验拓扑(分为静态路由和动态路由两种) 静态路由互通 动态路由互通 实验背景 这个是想实现外网与内网的连接跟网络的探讨,最终实现互通以及使用并且在网络地址转换后能使用网络然后再这个基础上再配置访问控制列表和网络地址转换的的学习过程。 实验需了解的知识…...

基于 Python、OpenCV 和 PyQt5 的人脸识别上课打卡系统
大家好,我是Java徐师兄,今天为大家带来的是基于 Python、OpenCV 和 PyQt5 的人脸识别上课签到系统。该系统采用 Python 语言开发,开发过程中采用了OpenCV框架,Sqlite db 作为数据库,系统功能完善 ,实用性强…...

MySQL 复合查询
实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张表EMP,DEPT,SALGRADE 来演示如何进行多表查询。表结构的代码以及插入的数据如下: DROP database IF EXISTS scott; CREATE database IF NOT EXIST…...

【Leetcode】19. 删除链表的第N个节点
【Leetcode】19. 删除链表的第N个节点 1. 题目介绍2. 方法一:计算链表长度逻辑流程:代码复杂度分析 1. 题目介绍 题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,…...

flutter底部导航栏中间按钮凸起,导航栏中间部分凹陷效果
关键代码: Scaffold中设置floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked和extendBody: true, BottomAppBar中设置shape: const CircularNotchedRectangle() Scaffold(extendBody: true,//body是否延伸脚手架底部,在底部导航…...

<项目代码>YOLOv8 红绿灯识别<目标检测>
YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…...
HTMLHTML5革命:构建现代网页的终极指南 - 4. 使用元素
HTML&HTML5革命:构建现代网页的终极指南 4. 使用元素 大家好,我是莫离老师。 到目前为止,我们已经了解了 HTML 和 HTML5 的基础概念,并且选择了适合自己的开发工具。 今天,我们将迈出实际开发的第一步,…...
使用 Selenium 和 Python 爬取腾讯新闻:从基础到实践
使用 Selenium 和 Python 爬取腾讯新闻:从基础到实践 在这篇博客中,我们将介绍如何利用 Selenium 和 Python 爬取腾讯新闻的内容,并将结果保存到 CSV 文件中。本教程包含以下内容: 项目简介依赖安装实现功能的代码实现中的关键技…...

CAD深度清理工具-AVappsDrawingPurge9.0.0(2024.8.27版本) 支持版本CAD2022-2025-供大家学习研究参考
图形文件DWG体积很大:通常没有明显的数据。同时,还其他症状包括: (1)无法复制和粘贴图元。 (2)悬挂较长时间选择文本与 “特性”选项板上打开。 (3)图形文件需要很长时间…...

vue3+vite使用vite-plugin-electron-renderer插件和script-loader插件有冲突
报错信息:Error: Dynamic require of "path" is not supported 报错问题是在使用vite-plugin-electron-renderer插件不支持import动态引入,该报错信息并不准确,实际原因是vite-plugin-electron-renderer插件和script-loader插件有…...

领养我的宠物:SpringBoot开发指南
第2章 开发环境与技术 本章节对开发宠物领养系统需要搭建的开发环境,还有宠物领养系统开发中使用的编程技术等进行阐述。 2.1 Java语言 Java语言是当今为止依然在编程语言行业具有生命力的常青树之一。Java语言最原始的诞生,不仅仅是创造者感觉C语言在编…...

直击高频编程考点:聚焦新版综合编程能力考查汇总
目录 一、业务性编程和广度能力考查 (一)基本定义 (二)必要性分析 二、高频考查样题(编程扩展问法) 考题1: 用java 代码实现一个死锁用例,说说怎么解决死锁问题?(高…...

【EI会议征稿 | ACM出版 】第六届计算机信息和大数据应用国际学术会议(CIBDA 2025)
大会官网:www.ic-cibda.org 大会时间:2025年3月14-16日 大会地点:中国-武汉 收录检索:EI Compendex,Scopus 接受/拒稿通知:投稿后约3~8天 大会简介 第六届计算机信息和大数据应用国际学术会议ÿ…...
淘宝商品数据获取:Python爬虫技术的应用与实践
引言 随着电子商务的蓬勃发展,淘宝作为中国最大的电商平台之一,拥有海量的商品数据。这些数据对于市场分析、消费者行为研究、商品推荐系统等领域具有极高的价值。然而,如何高效、合法地从淘宝平台获取这些数据,成为了一个技术挑…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...