数据库杂谈(七)——数据库的存储结构

文章目录

  • 7 数据库的存储结构
    • 7.1 数据库访问管理-文件组织
    • 7.2 数据库访问管理——索引技术

7 数据库的存储结构

让我们重新温习第六讲的所学知识。

image-20220307095007617

这个图实际上我们要关注的是蓝色箭头指向的那一层。在这一层之上,我们都是对SQL语句动手,而在这一层之下,我们是转为对文件系统动手。

记得我们在第一讲学过的数据库三层结构吗?

image-20211004004634420

从这个图上看,实际上上面这个图是最上面那张图的抽象。而物理层指的就是数据库文件在操作系统中的存储方式。

我们曾经在数据结构中学过,文件的结构有很多种,比如堆文件、哈希文件、倒排文件。那我们在操作系统中要用什么数据结构存储数据库文件呢?

事实上,在实际开发中,没有一种数据结构能够包治百病。所以选择合适的数据结构来存储数据库文件可以大幅提高查询的效率。在下面的小节中,我们会提到相关知识。

7.1 数据库访问管理-文件组织

经过开头的叙述,相信大多数同学都对本讲有一个大概的把握。我们可以把上述的知识点归结为下面两点:

  1. 传统的数据模型都以记录为基础。记录的集合构成文件。

  2. 文件须按照一定的结构组织和存储记录,访问有关的记录须经由一定的存取路径。对数据库的操作最终落实到对文件的操作。

我们首先要先思考一个问题,数据库系统在对底层文件进行访问的时候,有哪些访问类型。

查询文件的全部或相当多的记录

一般把访问15%以上记录的查询都归入这一类。

因为根据统计学规律,如果有15%以上的记录在硬盘上的话,那么我们我们可以理解为这15%几乎遍布所有的物理块,我们必须找 出全部的物理块才能找到这15%的记录。

查询某一特定记录

一般把访问某一条特定元组归为这一类。

查询某些记录

一般把访问15%以下记录的查询都归入这一类

范围查询

范围查询查询出来的元组有时候多有时候少,这取决于你指定的范围。如你要查询学生表里年龄在15到25之间的学生,这时候可能会出现多种情况:查询结果没有该年龄段的学生;查询结果只有一个学生;查询结果有很多学生;所有学生都处于该年龄段。

记录更新

比起查询操作,记录的更新要复杂的多,因为在更新的时候会引起记录位置的调整和相应的修改(比如索引就要改)。

缓冲池和物理块

在市面上,磁盘中的数据划分为大小相等的物理块,每个物理块之间要留有间隙,间隙通常放的是初始化信息和下一个物理块的地址信息。

实际上,我们读取磁盘的时候,并不是像1kb1kb那样的字节去读取的,我们是一个物理块一个物理块去读的。所以,我们通常把磁盘叫做块设备。像linux来说,一般一个物理块是1024个字节。现在假如我们有一个关系想要放入文件当中,此时关系中一个元组占一百个字节,那么我一个物理块能放10个元组左右,那么到时候我们读硬盘的时候,就是一块一块读的。比如我们查询的时候就是一块一块找,看这一块有无我们需要的东西。

而对于缓冲池来说,拿MySQL举例,其使用的是InnoDB存储引擎,其以页为单位来管理存储空间。而磁盘Ⅳ/o需要消耗的时间很多,而在内存中进行操作,效率则会高很多,为了能让数据表或者索引中的数据随时被我们所用,DBMS会申请占用内存来作为数据缓冲池,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。
这样做的好处是可以让磁盘活动最小化,从而减少与磁盘直接进行工/0 的时间。要知道,这种策略对提升sQL语句的查询性能来说至关重要。如果索引的数据在缓冲池里,那么访问的成本就会降低很多。

虽然数据库基于操作系统之上,其所有数据库文件最终落实到操作系统之中。但是这并不代表他就要使用操作系统的文件管理系统,这是有很多原因的,下面我们列举一下:

  1. DBMS为了实现其功能,须在文件目录、文件描述块、物理块等部分附加一些信息,而传统的文件系统是不提供这些信息的。
  2. 传统的文件系统主要面向批处理,而在数据库系统中,常常要求即席访问、动态修改。这就要求文件结构能够适应数据的动态变化,提供快速访问路径。
  3. 传统的文件基本上是为某一用户或者某类用户服务的,用途比较单一,共享的程度较低;而数据库中文件是供所有数据库用户共享的,甚至有些用途是不可预知的。这就要求数据库的文件结构兼顾多方面的要求,提供多种访问路径。
  4. 如果采用操作系统的文件管理系统作为DBMS的物理层的实现基础,则DBMS对操作系统的依赖不大,不利于DBMS的移植。
  5. 传统的文件一旦建立,数据量是比较稳定的;而数据库中文件的数据量变化较大,数据库中的文件结构应能适应这样的变化。

为了改变传统操作系统中的文件管理系统的不足,DBMS提供了多种文件结构。

堆文件

在数据结构中,只要涉及到用new(这里是采用C++说法)开辟内存空间存数据的,都是堆文件。

堆文件就类似堆东西一样,不停的往尾巴放东西,不停的在尾巴后插入数据。但是堆文件不一定是顺序结构,可以是链表结构。在查找的时候我们要通过顺序扫描,即从头到尾找,而且最坏的情况是你找到最后才找到。

很明显,堆文件对于查询文件的全部或相当多的记录有相当好的效果。

直接文件(哈希文件)

直接文件中,将记录的某一属性用哈希函数(在数据库里面我们以后叫做散列函数)直接映射成记录的地址,被散列的属性称为散列键。

说成大白话就是,你看书看到某一页,你喜欢在这一页加入书签;而哈希文件的原理就是,将你频繁使用那几条元组加上“标记”,然后将这些标记放入散列柜(类似于商城的存储柜)。当你需要查找柜中的元组,你只需要提供对应的标记即可查找到,而无需去”原数据“中顺序扫描浪费时间。

索引文件(堆文件配合B+树索引)

如果我们是要查找某一条元组,为了找出这条元组去堆文件里做顺序扫描来查找,显然效率不高,所以我们一般是在主键上建一个B+树索引,当我们要找某个值的时候,根据叶节点(相当于路标)去查找这个值所在的叶节点。

如果我们要做范围查询,利用B+树索引叶节点上面的链表也可以做双向索引。

索引可以建立多个,甚至是建立复合索引都可以。但是索引并不是建立得越多越好,我们是在建立索引的代价和效率两者之间折中的。

需要知道的是,最经典的MySQL就是采用B+树索引技术。

7.2 数据库访问管理——索引技术

在前面我们曾经挖了一个坑——磁盘的结构。实际上,如果你不是跨专业考研,你都应该学过计算机组成原理,这实际上是计组的知识。

image-20211008110848492

说明:首先,左边有很多盘片,右边是磁头臂,下面有个两个马达,盘片马达驱动磁盘旋转,磁头臂的马达可以驱动磁头臂移动,方便读取磁盘片上的数据。

然而如果你用操作系统中的文件系统存储的话,文件在磁盘上的地址是不确定的(这里指的不是路径,是内存地址),如果是利用FAT(微软发明的文件配置表)和NTFS去寻找文件位置,他会依靠之前存取的时候存储的碎片化位置去寻找,这样就会造成寻找文件的效率变低,如果你想把文件存在同一个磁盘片中,而且物理地址连续,那么操作系统是做不到的。

在磁盘中,有个固定操作叫寻道,他的过程就是将磁力壁定在磁盘片上的某条轨道(磁道)切割磁力线,从而寻找文件的地址。在这个过程中,通过移动磁头臂来寻道。根据摩尔定律,集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍。换言之,处理器的性能每隔两年翻一倍。可对于寻道来说,这是一个机械移动,对于应用在电子设备的摩尔定律显然不适用。也就是说,我们无法通过对硬件的升级来解决效率的问题。所以如果想提高效率问题,一定要把文件的内容根据物理地址按顺序排列好,减少磁头的移动。

image-20211003092136162

每个盘片的盘面被划分成多个狭窄的同心圆环,数据就存储在这样的同心圆环上面,我们将这样的圆环称为磁道 (Track)。每个盘面可以划分多个磁道,最外圈的磁道是0号磁道,向圆心增长依次为1磁道、2磁道…磁盘的数据存放就是从最外圈开始的。

image-20211003092215535

根据硬盘的规格不同,磁道数可以从几百到成千上万不等。每个磁道可以存储数 Kb 的数据,但是计算机不必要每次都读写这么多数据。因此,再把每个磁道划分为若干个弧段,每个弧段就是一个扇区 (Sector)。扇区是硬盘上存储的物理单位,现在每个扇区可存储 512 字节数据已经成了业界的约定。也就是说,即使计算机只需要某一个字节的数据,但是也得把这个 512 个字节的数据全部读入内存,再选择所需要的那个字节。

磁盘的存取实际由三部分构成:寻道时间旋转延迟传输时间。磁盘通过磁头臂的机械移动来寻道,寻道时间要比其他两部分时间大得多,所以为了有效地访问磁盘,我们应该尽可能地一次I/O连续访问较多的数据,减少I/O次数,从而减少寻道和选择延迟的次数。

在早期的DBMS中,常由操作系统来分配数据库所需的物理块,逻辑上相邻的物理块分散到磁盘的不同区域。在连续访问数据库中的数据时,性能严重下降,所以在现代DBMS中,都改由DBMS在初始化时向操作系统一次性申请所需的磁盘空间,让DBMS去分配这些物理块。DBMS主要分配方式主要有以下四种:

  1. 连续分配法:有点像顺序表,即物理位置上是连续的。
  2. 链接分配法:有点像链表,也就是逻辑位置上连续。
  3. 簇集分配法:物理连续逻辑也连续。
  4. 索引分配法:每个文件都有一个逻辑块号与其物理块地址对照的索引,通过索引,你可以找到文件中任何一块的地址。

在数据库设计中,如果一直频繁地用某个属性来检索某一条元组的话,那我们就可以根据这个属性把对应的元组用簇集的方式去建立,这样的话查找的时候效率非常快。但是,我们建簇集这个属性一定要很少更新,否则维护簇集的代价会很大。

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

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

相关文章

JSP中直接在输入框中校验

jsp: <label class"control-label col-sm-2" for"codeAdd">险种代码<span style"color: red;">*</span></label> <div classcontrols col-sm-4> <input class"form-control remote-validate" data-r…

【iCore3 双核心板_FPGA】例程十二:Modelsim仿真实验

实验指导书及代码包下载&#xff1a; 链接&#xff1a;http://pan.baidu.com/s/1hs4zNFY 密码&#xff1a;5z62 iCore3 购买链接&#xff1a; https://item.taobao.com/item.htm?id524229438677

机器学习的练功方式(五)——模型选择及调优

文章目录5 模型选择及调优5.1 数据增强5.2 过拟合5.3 交叉验证5.4 超参数搜索——网格搜索5 模型选择及调优 5.1 数据增强 有时候&#xff0c;你和你的老板说你数据不够&#xff0c;它是不会理你的。老板会发问&#xff1a;为什么你是做机器学习的要那么多数据干嘛&#xff0…

关于内存的一些基础知识

1、free&#xff1a;Display amount of free and used memory in the system. free显示的数值来自/proc/meminfo&#xff08;默认单位是KB&#xff09;。各个项的含义分别是&#xff1a; 1&#xff09;Mem这一行&#xff0c;shared&#xff1a;已废弃&#xff1b;buffers&#…

Flask 单例模式 session

一、单例模式 单例模式分为四种&#xff1a;基于文件的单例模式&#xff0c;基于类方法的单例模式&#xff0c;基于__new__的单例模式&#xff0c;基于metaclass的单例模式 1. 基于类方法的单例模式 - 不支持多线程模式 import threadingclass Singleton(object):def __init__(…

数据处理工具(一)——Matplotlib

文章目录致谢1 Matplotlib1.1 什么是Matplotlib1.2 实现一个简单的图1.3 Matplotlib三层结构1.3.1 容器层1.3.2 辅助显示层1.3.3 图像层1.3 使用模块1.3.1 画布的设置1.3.2 添加网格辅助背景1.3.3 附加属性1.3.4 标签1.3.5 刻度1.3.6 一个图上多条线1.3.7 子区域1.4 基础图表1.…

Java解析Rss(三)

2019独角兽企业重金招聘Python工程师标准>>> package com.ninemax.application.rss;import java.net.URL; import java.text.SimpleDateFormat; import java.util.List;import com.sun.syndication.feed.synd.SyndCategory; import com.sun.syndication.feed.synd.S…

Redis服务器启动之后3个警告信息的解决方案

今天是年前最后一篇文章了&#xff0c;不想写太多的东西&#xff0c;就写一些有关Redis相关问题的解决方案。当我们启动了Redis服务器之后&#xff0c;会看到3个警告&#xff0c;如果没看到&#xff0c;那是很好的&#xff0c;但是我看到了。看到了就不能不管&#xff0c;所以就…

ASP .NET MVC 之Entity Framework入门教程及源码

本文主要的目的是 1. 说明Entity Framework Power Tools如何使用。 2. Entity Framework 快速门 实验环境&#xff1a; OS: Windows Server 2012, Windows 7 DE: VS2013 MVC 6.0Entity Framework SQL Server 2012 准备工作 基于现有数据库生成POCO数据类和数据库上下文需要借…

机器学习的练功方式(六)——朴素贝叶斯

文章目录致谢6 朴素贝叶斯6.1 概述6.2 概率论6.2.1 大数定律6.2.2 基本概念6.2.3 极大似然估计6.2.4 多项式分布6.2.4.1 伯努利分布6.2.4.2 二项分布6.2.5 朴素贝叶斯6.3 朴素贝叶斯文本分类6.3.1 一个例子6.3.2 拉普拉斯平滑系数6.3.3 算法实现6.4 贝叶斯分类器6.4.1 多项式贝…

数据库杂谈(八)——查询优化

文章目录8 查询优化8.1 概述8.2 查询数和语法树8.3 代数优化8.4 物理优化8.5 连接操作优化8.5.1 嵌套循环法8.5.2 利用B树索引或哈希索引寻找匹配元组法8.5.3 散列连接法8.6 后话8 查询优化 8.1 概述 我们不管是在数据库软件如MySQL、SQLServer等&#xff0c;还是通过应用程序…

Android-入门学习笔记-使用 CursorLoader 加载数据

3 使用这个代码片段开始练习 也可以参考 Codepath 教程 高级内容补充: 你是否在思考ArrayAdapter’s 的 getView() 方法和CursorAdapter 的 newView() 和 bindView() 方法? 你可以查看 CursorAdapter 类的源码. getView() 方法依然存在, 但是它实际根据是否存在列表项能够被循…

在 Angularjs 中 ui-sref 和 $state.go 如何传递参数

1 ui-sref、$state.go 的区别 ui-sref 一般使用在 <a>...</a>&#xff1b; <a ui-sref"message-list">消息中心</a> $state.go(someState)一般使用在 controller里面&#xff1b; .controller(firstCtrl, function($scope, $state) {$state.…

机器学习的练功方式(七)——决策树

文章目录致谢7 决策树7.1 认识决策树7.2 决策树原理7.3 信息论7.3.1 信息熵7.3.1.1 熵7.3.1.2 信息7.3.1.3 信息熵7.3.2 信息增益7.4 决策树实现7.5 决策图7.6 后话致谢 信息熵是什么&#xff1f; - 知乎 (zhihu.com) 没有免费午餐定理_百度百科 (baidu.com) 7 决策树 决策树(…

机器学习的练功方式(八)——随机森林

文章目录致谢8 随机森林8.1 引入8.2 决策森林8.2.1 集成学习方法8.2.2 什么是随机森林8.2.3 无偏估计8.2.4 决策森林原理过程8.2.5 决策森林算法实现8.3 总结致谢 如何理解无偏估计&#xff1f;无偏估计有什么用&#xff1f;什么是无偏估计&#xff1f;_司南牧|知乎|博客|易懂教…

并行计算(一)——并行计算机系统及结构模型

致谢 SMP、COW、PVP、MPP计算机相关_神.秘.人的博客-CSDN博客_并行向量处理机 1 并行计算机系统及结构模型 1.1 并行计算 在下面的讲解之前&#xff0c;我们先看一下并行计算的量纲。 1.1.1 并行计算和计算机科学 随着计算机和计算机学科的发展&#xff0c;所有的学科都转向…

【机器学习实战】极大似然法

2019独角兽企业重金招聘Python工程师标准>>> http://baike.baidu.com/link?url3Ej1VIItwWd35sXeoRWRhcJkJLCFvzPzNIoTkAfai8ZIS4Ppcch4_maQ25FjNCU1Eplsp4k3oPKLyv6VIsPhsq 一、 最大似然法是一种具有理论性的点估计法&#xff0c;基本思想是&#xff0c;当从模型…

机器学习的练功方式(九)——线性回归

文章目录致谢9 线性回归再相遇9.1 再遇9.1.1 概述9.1.2 矩阵和向量9.1.3 矩阵加减乘除9.1.3.1 矩阵——矩阵加减9.1.3.2 矩阵——标量加减乘9.1.3.3 矩阵——向量相乘9.1.3.4 矩阵——矩阵相乘9.1.3.5 矩阵的逆9.1.3.6 矩阵的转置9.1.4 向量化9.1.5 广义线性模型9.2 正规方程9.…

12个月份统计分组

/** 根据月份来统计trade里面的入账&#xff0c;支出&#xff0c;总盈利*/public function countMonth(){$in array();$out array();$res array();$year date("Y",time());$in_sql SELECT SUM(money) AS mon, FROM_UNIXTIME(cdate, "%m") AS m FR…

idea 调试技巧1

1 多线程调试 开发过多线程应用的朋友应该有体会&#xff0c;有些时候&#xff0c;为了观察多个线程间变量的不同状态&#xff0c;以及锁的获取等&#xff0c;就会想到在代码里加个断点debug一下。 在IDE里断点停下来的时候&#xff0c;可以切换到另外的线程中&#xff0c;跑其…