2 关系型数据库是如何工作的

很多人在学习数据库知识的时候,知识点都是比较分散的,本章旨在将数据库知识进行整合串联,使之可以达到知其所以然的地步。

从数据结构说起

(1)时间复杂度

对于数据库本身而言,重要不仅仅是数据量,而是在数据量增长之后如何增加相应的运算能力?
时间复杂度用来检验某个算法处理一定量的数据要花多长时间,时间复杂度不会给出确切的运算次数,但是给出的是一种理念。
在这里插入图片描述(1) 绿:O(1)或者叫常数阶复杂度,保持为常数(要不人家就不会叫常数阶复杂度了)。
(2)红:O(log(n))对数阶复杂度,即使在十亿级数据量时也很低。
(3)粉:最糟糕的复杂度是 O(n^2),平方阶复杂度,运算数快速膨胀。
(4)黑和蓝:另外两种复杂度(的运算数也是)快速增长。
如果要处理2000条元素?
O(1) 算法会消耗 1 次运算
O(log(n)) 算法会消耗 7 次运算
O(n) 算法会消耗 2000 次运算
O(n*log(n)) 算法会消耗 14,000 次运算
O(n^2) 算法会消耗 4,000,000 次运算

(2)归并排序

理解 sort() 函数的工作原理

(3)二叉搜索树

数据库中查询的时间复杂度,是我们无法使用矩阵,转而使用二叉搜索树
二叉搜索树只需 log(N) 次运算,而如果你直接使用阵列则需要 N 次运算

(4)B+树索引

查找一个特定值这个树挺好用,但是当你需要查找两个值之间的多个元素时,就会有大麻烦了。你的成本将是 O(N),因为你必须查找树的每一个节点,以判断它是否处于那 2 个值之间(例如,对树使用中序遍历)。而且这个操作不是磁盘I/O有利的,因为你必须读取整个树。
这就是为什么引入B+树索引
如果你在数据库中增加或删除一行(从而在相关的 B+树索引里):
(1)你必须在B+树中的节点之间保持顺序,否则节点会变得一团糟,你无法从中找到想要的节点.
(2)你必须尽可能降低B+树的层数,否则 O(log(N)) 复杂度会变成 O(N).

(5)哈希表

当你想快速查找值时,哈希表是非常有用的。而且,理解哈希表会帮助我们接下来理解一个数据库常见的联接操作,叫做『哈希联接』。这个数据结构也被数据库用来保存一些内部的东西(比如锁表或者缓冲池,我们在下文会研究这两个概念)。

为什么不用阵列呢?
(1)如果有了好的哈希函数,在哈希表里搜索的时间复杂度是 O(1)。
(2)一个哈希表可以只装载一半到内存,剩下的哈希桶可以留在硬盘上。
(3)用阵列的话,你需要一个连续内存空间。如果你加载一个大表,很难分配足够的连续内存空间.

全局概览

我们已经了解了数据库内部的部分重要算法,现在我们需要回来看看数据库的全貌了。
数据库一般可以用如下图形来理解:
在这里插入图片描述

核心组件

(1)进程管理器(process manager):很多数据库具备一个需要妥善管理的进程/线程池。再者,为了实现纳秒级操作,一些现代数据库使用自己的线程而不是操作系统线程。
(2)网络管理器(network manager):网路I/O是个大问题,尤其是对于分布式数据库。所以一些数据库具备自己的网络管理器。
(3)文件系统管理器(File system manager):磁盘I/O是数据库的首要瓶颈。具备一个文件系统管理器来完美地处理OS文件系统甚至取代OS文件系统,是非常重要的。
(4)内存管理器(memory manager):为了避免磁盘I/O带来的性能损失,需要大量的内存。但是如果你要处理大容量内存你需要高效的内存管理器,尤其是你有很多查询同时使用内存的时候。
(5)安全管理器(Security Manager):用于对用户的验证和授权。
(6)客户端管理器(Client manager):用于管理客户端连接。

Tools

(1)备份管理器(Backup manager):用于保存和恢复数据。
(2)恢复管理器(Recovery manager):用于崩溃后重启数据库到一个一致状态。
(3)监控管理器(Monitor manager):用于记录数据库活动信息和提供监控数据库的工具
(4)管理员管理器(Administration manager):用于保存元数据(比如表的名称和结构),提供管理数据库、模式、表空间的工具。

Query Manager

(1)查询解析器(Query parser):用于检查查询是否合法
(2)查询重写器(Query rewriter):用于预优化查询
(3)查询优化器(Query optimizer):用于优化查询
(4)查询执行器(Query executor):用于编译和执行查询

Data Manager

(1)事务管理器(Transaction manager):用于处理事务
(2)缓存管理器(Cache manager):数据被使用之前置于内存,或者数据写入磁盘之前置于内存.
(3)数据访问管理器(Data access manager):访问磁盘中的数据

数据查询的流程(Client Manager)
客户端管理器是处理客户端通信的。客户端可以是一个(网站)服务器或者一个最终用户或最终应用。客户端管理器通过一系列知名的APIJDBC, ODBC, OLE-DB …)提供不同的方式来访问数据库。客户端管理器也提供专有的数据库访问API

在这里插入图片描述
当你连接到数据库时:

(1)管理器首先检查你的验证信息(用户名和密码),然后检查你是否有访问数据库的授权。这些权限由DBA分配。
(2)然后,管理器检查是否有空闲进程(或线程)来处理你对查询.
(3)管理器还会检查数据库是否负载很重.
(4)管理器可能会等待一会儿来获取需要的资源。如果等待时间达到超时时间,它会关闭连接并给出一个可读的错误信息。
(5)然后管理器会把你的查询送给查询管理器来处理.
(6)因为查询处理进程不是『不全则无』的,一旦它从查询管理器得到数据,它会把部分结果保存到一个缓冲区并且开始给你发送。
(7)如果遇到问题,管理器关闭连接,向你发送可读的解释信息,然后释放资源。
查询管理器
这部分是数据库的威力所在,在这部分里,一个写得糟糕的查询可以转换成一个快速执行的代码,代码执行的结果被送到客户端管理器。

在这里插入图片描述
这个多步骤操作过程如下:

(1)查询首先被解析并判断是否合法
(2)然后被重写,去除了无用的操作并且加入预优化部分
(3)接着被优化以便提升性能,并被转换为可执行代码和数据访问计划。
(4)然后计划被编译
(5)最后,被执行
查询解析器
每一条SQL语句都要送到解析器来检查语法,如果你的查询有错,解析器将拒绝该查询.
但这还不算完,解析器还会检查关键字是否使用正确的顺序,比如 WHERE 写在 SELECT 之前会被拒绝。

然后,解析器要分析查询中的表和字段,使用数据库元数据来检查:

(1)表是否存在
(2)表的字段是否存在
(3)对某类型字段的 运算 是否 可能(比如,你不能将整数和字符串进行比较,你不能对一个整数使用 substring() 函数)
a.接着,解析器检查在查询中你是否有权限来读取(或写入)表。这些权限由DBA分配。
b.在解析过程中,SQL 查询被转换为内部表示(通常是一个树)
c.如果一切正常,内部表示被送到查询重写器。
查询重写器

在这一步,我们已经有了查询的内部表示,重写器的目标是:

(1)预优化查询
(2)避免不必要的运算
(3)帮助优化器找到合理的最佳解决方案

重写器按照一系列已知的规则对查询执行检测。如果查询匹配一种模式的规则,查询就会按照这条规则来重写。下面是(可选)规则的非详尽的列表:

1.视图合并:如果你在查询中使用视图,视图就会转换为它的 SQL 代码。
2.子查询扁平化:子查询是很难优化的,因此重写器会尝试移除子查询

例如:

SELECT PERSON.*
FROM PERSON
WHERE PERSON.person_key IN
(SELECT MAILS.person_key
FROM MAILS
WHERE MAILS.mail LIKE 'christophe%');

会转换为:

SELECT PERSON.*
FROM PERSON, MAILS
WHERE PERSON.person_key = MAILS.person_key
and MAILS.mail LIKE 'christophe%';
1.去除不必要的运算符:比如,如果你用了 DISTINCT,而其实你有 UNIQUE 约束(这本身就防止了数据出现重复),那么 DISTINCT 关键字就被去掉了。
2.排除冗余的联接:如果相同的 JOIN 条件出现两次,比如隐藏在视图中的 JOIN 条件,或者由于传递性产生的无用 JOIN,都会被消除。
3.常数计算赋值:如果你的查询需要计算,那么在重写过程中计算会执行一次。比如 WHERE AGE > 10+2 会转换为 WHERE AGE > 12TODATE(“日期字符串”) 会转换为 datetime 格式的日期值。
4.(高级)分区裁剪(Partition Pruning):如果你用了分区表,重写器能够找到需要使用的分区。
5.(高级)物化视图重写(Materialized view rewrite):如果你有个物化视图匹配查询谓词的一个子集,重写器将检查视图是否最新并修改查询,令查询使用物化视图而不是原始表。
6.(高级)自定义规则:如果你有自定义规则来修改查询(就像 Oracle policy),重写器就会执行这些规则。
7.(高级)OLAP转换:分析/加窗 函数,星形联接,ROLLUP 函数……都会发生转换(但我不确定这是由重写器还是优化器来完成,因为两个进程联系很紧,必须看是什么数据库)
统计
数据库和操作系统如何保存数据。两者使用的最小单位叫做页或块(默认 48 KB)。这就是说如果你仅需要 1KB,也会占用一个页。要是页的大小为 8KB,你就浪费了 7KB

当你要求数据库收集统计信息,数据库会计算下列值:

1.表中行和页的数量
2.表中每个列中的:--唯一值--数据长度(最小,最大,平均)--数据范围(最小,最大,平均)
3.表的索引信息

这些统计信息会帮助优化器估计查询所需的磁盘 I/O、CPU、和内存使用

对每个列的统计非常重要。比如,如果一个表 PERSON 需要联接 2 个列: LAST_NAME, FIRST_NAME。根据统计信息,数据库知道FIRST_NAME只有 1,000 个不同的值,LAST_NAME1,000,000 个不同的值。因此,数据库就会按照 LAST_NAME, FIRST_NAME 联接。因为 LAST_NAME 不大可能重复,多数情况下比较 LAST_NAME 的头 23 个字符就够了,这将大大减少比较的次数。

不过,这些只是基本的统计。你可以让数据库做一种高级统计,叫直方图。直方图是列值分布情况的统计信息。例如:

1.出现最频繁的值
2.出现最频繁的值
......
这些额外的统计会帮助数据库找到更佳的查询计划,尤其是对于等式谓词(例如: WHERE AGE = 18 )或范围谓词(例如: WHERE AGE > 10 and AGE < 40),因为数据库可以更好的了解这些谓词相关的数字类型数据行(注:这个概念的技术名称叫选择率)

统计信息保存在数据库元数据内,例如(非分区)表的统计信息位置:

1.Oracle: USER / ALL / DBA_TABLESUSER / ALL / DBA_TAB_COLUMNS
2.DB2SYSCAT.TABLESSYSCAT.COLUMNS

统计信息必须及时更新。如果一个表有 1,000,000 行而数据库认为它只有 500 行,没有比这更糟糕的了。统计唯一的不利之处是需要时间来计算,这就是为什么数据库大多默认情况下不会自动计算统计信息。数据达到百万级时统计会变得困难,这时候,你可以选择仅做基本统计或者在一个数据库样本上执行统计。

查询优化器
所有的现代数据库都在用基于成本的优化(即CBO)来优化查询。道理是针对每个运算设置一个成本,通过应用成本最低廉的一系列运算,来找到最佳的降低查询成本的方法。

举例:即便一个简单的联接查询对于优化器来说都是个噩梦

索引
1. 要记住一点,索引都是已经排了序的
2. 另外,很多现代数据库为了改善执行计划的成本,可以仅为当前查询动态地生成临时索引
存取路径

在应用联接运算符(join operators)之前,你首先需要获得数据。以下就是获得数据的方法:

1.全扫描--简单的说全扫描就是数据库完整的读一个表或索引。就磁盘 I/O 而言,很明显全表扫描的成本比索引全扫描要高昂
2.范围扫描--其他类型的扫描有索引范围扫描,比如当你使用谓词 ” WHERE AGE > 20 AND AGE < 40 ” 的时候它就会发生(当然,你需要在 AGE 字段上有索引才能用到索引范围扫描)
3.唯一扫描--你只需要从索引中取一个值可以用唯一扫描
4.根据 ROW ID 存取--多数情况下,如果数据库使用索引,它就必须查找与索引相关的行,这样就会用到根据 ROW ID 存取的方式。例如,假如你运行:SELECT LASTNAME, FIRSTNAME from PERSON WHERE AGE = 28如果 person 表的 age 列有索引,优化器会使用索引找到所有年龄为 28 的人,然后它会去表中读取相关的行,这是因为索引中只有 age 的信息而你要的是姓和名但是,假如你换个做法:SELECT TYPE_PERSON.CATEGORY from PERSON ,TYPE_PERSONWHERE PERSON.AGE = TYPE_PERSON.AGEPERSON 表的索引会用来联接 TYPE_PERSON 表,但是 PERSON 表不会根据行ID 存取,因为你并没有要求这个表内的信息。虽然这个方法在少量存取时表现很好,这个运算的真正问题其实是磁盘 I/O。假如需要大量的根据行ID存取,数据库也许会选择全扫描
联接运算符

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关键词搜索亚马逊商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

亚马逊提供了API接口来获取商品数据。其中&#xff0c;关键词搜索亚马逊商品接口&#xff08;item_search-按关键字搜索亚马逊商品接口&#xff09;可以用于获取按关键字搜索到的商品数据。 通过该接口&#xff0c;您可以使用API Key和API Secret来认证身份&#xff0c;并使用…

电子电器架构 —— 车载网关初入门(二)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数5000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他…

麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器

原文链接&#xff1a;麒麟KYLINIOS软件仓库搭建01-新创建软件仓库服务器 hello&#xff0c;大家好啊&#xff0c;今天给大家带来麒麟桌面操作系统软件仓库搭建的文章01-新创建软件仓库服务器&#xff0c;本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版本上搭建内网…

MySQL数据库操作、表操作和常用数据类型

1、数据库操作 1.1 创建数据库 语法&#xff1a;CREATE DATABASE [IF NOT EXISTS] 数据库名 charset utf8;&#xff08;注意字母不区分大小写&#xff0c;分号为英文输入法&#xff09;&#xff0c;[ ]为可选项&#xff0c;意思为如果系统没有想要创建&#xff08;数据库名&am…

酷克数据出席永洪科技用户大会 携手驱动商业智能升级

10月27日&#xff0c;第7届永洪科技全国用户大会在北京召开。酷克数据作为国内云原生数仓代表企业&#xff0c;受邀出席本次大会&#xff0c;全面展示了云数仓领域最新前沿技术&#xff0c;并进行主题演讲。 携手合作 助力企业释放数据价值 数据仓库是商业智能&#xff08;BI…

Simulink的To Workspace

To Workspace模块将Simulink产生的数据存储到matlab的工作区。 用To Workspace模块中的数据进行绘图。 参见Matlab/simulink/simscape multibody-to wotkspace模块使用_to workspace模块_五VV的博客-CSDN博客To workspace模块入门详解_哔哩哔哩_bilibili&#xff08;很好&#…

[极客大挑战 2019]LoveSQL 1

题目环境&#xff1a;判断注入类型是否为数字型注入 admin 1 回显结果 否 是否为字符型注入 admin 1 回显结果 是 使用堆叠注入 采用密码参数进行注入 爆数据库1; show database();#回显结果 这里猜测注入语句某字段被过滤&#xff0c;或者是’;被过滤导致不能堆叠注入 爆字段数…

项目资源不足,常见的5种处理方式

软件开发中&#xff0c;经常会遇到项目资源不足的情况&#xff0c;项目团队如果无法及时获得所需的人力、财力、物力等资源&#xff0c;往往会影响团队士气以及任务质量&#xff0c;造成无法按时完成任务&#xff0c;进而影响项目进度。 因此及时处理和应对资源不足的情况&…

Linux 命令|服务器相关

1. 在公共 linux 上创建 python 虚拟环境 【精选】在公共Linux服务器上创建自己的python虚拟环境_服务器创建自己的环境-CSDN博客 2. 查看现存的状态&#xff0c;看有没有程序在跑 nvidia-smi命令详解-CSDN博客 3. 上传本地文件到服务器 在本地 Mac 计算机的终端中&#x…

【MATLAB第81期】基于MATLAB的LSTM长短期记忆网络预测模型时间滞后解决思路(更新中)

【MATLAB第81期】基于MATLAB的LSTM长短期记忆网络预测模型时间滞后解决思路&#xff08;更新中&#xff09; 在LSTM预测过程中&#xff0c;极易出现时间滞后&#xff0c;类似于下图&#xff0c;与一个以上的样本点结果错位&#xff0c;产生滞后的效果。 在建模过程中&#xf…

【Python语言速回顾】——数据可视化基础

目录 引入 一、Matplotlib模块&#xff08;常用&#xff09; 1、绘图流程&常用图 ​编辑 2、绘制子图&添加标注 ​编辑 3、面向对象画图 4、Pylab模块应用 二、Seaborn模块&#xff08;常用&#xff09; 1、常用图 2、代码示例 ​编辑 ​编辑 ​编辑 ​…

kafka为什么如此之快?

天下武功&#xff0c;唯快不破。同样的&#xff0c;kafka在消息队列领域&#xff0c;也是非常快的&#xff0c;这里的块指的是kafka在单位时间搬运的数据量大小&#xff0c;也就是吞吐量&#xff0c;下图是搬运网上的一个性能测试结果&#xff0c;在同步发送场景下&#xff0c;…

Java SE 学习笔记(十七)—— 单元测试、反射

目录 1 单元测试1.1 单元测试概述1.2 单元测试快速入门1.3 JUnit 常用注解 2 反射2.1 反射概述2.2 获取类对象2.3 获取构造器对象2.4 获取成员变量对象2.5 获取常用方法对象2.6 反射的作用2.6.1 绕过编译阶段为集合添加数据2.6.2 通用框架的底层原理 1 单元测试 1.1 单元测试概…

【Linux】常见的Linux命令

目录 一、与目录有关的操作 二、与文件有关的操作 三、针对目录的操作 三、在linux上搭建环境 一、与目录有关的操作 1.ls 显示目录内容列表 ls / 这里的 / 表示根目录&#xff0c;相当于windows中的此电脑&#xff0c;linux中没有盘符。 ls -l / 显示详细信息 可以…

Redis Twemproxy 集群,水平扩展 ,扩容方案

文章目录 一、概述二、Twemproxy 分布模式三、测试规划四、Redis 服务实例准备4.1 配置Redis实例4.2 创建关资源4.3 启动Redis服务实例 五、Twemproxy 安装准备六、Twemproxy 安装及集群配置6.1 安装 Twemproxy6.2 配置 Twemproxy6.3 启动 twemproxy6.4 测试 twemproxy 集群 如…

基于Spring Boot的大学课程排课系统设计与实现

摘 要 大学课程排课是现代教育管理中重要的一环。目前&#xff0c;传统的排课方式已经无法满足日益增长的课程需求和学生个性化的诉求。因此&#xff0c;研究一种基于遗传算法的大学课程排课系统是非常必要的。本研究旨在开发一种基于SpringBoot Vue的大学课程排课系统&#x…

[架构之路-252/创业之路-83]:目标系统 - 纵向分层 - 企业信息化的呈现形态:常见企业信息化软件系统 - 企业应用信息系统集成

目录 第一章 什么是企业应用信息系统集成What 1.1 简介 1.2 架构 二、为什么需要企业应用信息系统集成Why 三、如何实现企业应用信息系统集成 3.1 步骤 3.2 企业应用集成的层次 3.3 业务流程重组 第一章 什么是企业应用信息系统集成What 1.1 简介 企业应用信息系统集…

HDFS 读写架构

一、组成架构 1、NameNode(NN) : 集群的Master&#xff0c;它是一个主管&#xff0c;管理者 (1) 管理HDFS的命名空间 (2) 配置副本策略 (3) 管理数据块(Block)映射信息 (4) 处理客户端读写请求 2、DataNode(DN) : 集群的Slave。NN下达命令&#xff0c;DataNode执行实际操作。…

最新版付费进群源码带自动定位和分销以及分站功能完整版无加密

简介 看到别人发那些不是挂羊头卖狗肉&#xff0c;要么就是发的缺少文件引流的。非常滴恶心 这源码是我付费花钱买的免费分享给大家&#xff0c;功能完整。而且无加密 功能&#xff1a;新建分销会员&#xff0c;设置账号密码&#xff0c;收款方式等 说明&#xff1a; 分站…

Flutter 04 按钮Button和事件处理、弹框Dialog、Toast

一、按钮组件 1、按钮类型&#xff1a; 2、按钮实现效果&#xff1a; import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);overrideWidget build(BuildContext co…