[转载] --- 数据库基本知识

里面的很多点,我之前都总结过,但是感觉这篇把这些都连起来了,总结的挺好,转载保存一下


【从入门到入土】令人脱发的数据库底层设计

前言

说到数据库这个词,我只能用爱恨交加这个词来形容它。两年前在自己还单纯懵懂的时候进了数据库的课堂,听完数据库的课,觉得这是一门再简单不过的课程,任何一门编程语言都比SQL要晦涩难懂,任何一门理论课程都比数据库关系要复杂得多。直到从被面试官按在地上摩擦,到工作中那一条条令人发指的慢查询SQL,这就已经完全颠覆了我对数据库的看法。在有各种数据库工具的今天,我们是看不到那简单到不能再简单的一张表的背后,隐藏着多少数据结构的支撑,也看不到我们随手敲的一条SELECT,背后会有多少算法和数据结构在给我们做优化,作为一个有技术热情的coder,应该需要对我们每日在用的数据库做一次深入了解。

数据库架构

  • 如何设计一个关系型数据库

    这个问题很宽泛,需要我们对于整体有一个掌控,对我们平时所用的数据库要有足够的了解,对整个数据库做模块划分是这道题的关键,这就更需要我们足够了解数据库,对数据库做一个合理的模块设计。

  • 设计

    从开始,首先要明白,数据库的最最根本的作用是什么——存储数据,所以我们需要一个存储模块来存储我们的数据,它可以是一个文件系统(机械硬盘?SSD固态硬盘?)。但光有存储模块是不够的,我们还需要一个程序实例,来组织或者获取这些数据,在程序实例中我们需要提供获取和组织这些数据的方式,所以我们需要在程序实例中实现存储管理模块。我们还可以在存储管理模块中做一些提升效能的工作,例如同时读取多行分块分页存储等。数据库作为一款对性能要求极高的软件,我们应该加入缓存机制,来提高其速度,当查询到缓存中已存在的数据,我们应该直接将其从缓存中读取,这样可以减少硬盘IO次数,提高效能。到这里为止,我们已经完成了对数据库的存储方面的功能设计,但是作为数据库,应该需要提供给用户对数据进行增删改查的接口,即平时所写的SQL,所以我们应该提供一个SQL解析模块,来对日常用户所写的SQL语句进行解析,转换成机器可识别的指令,我们也可以直接将编译过的SQL加入缓存,下次再有同样的SQL就直接从缓存中读取,同样可以提高效能。作为一款成熟的数据库,需要应对各种复杂的环境,要时刻记录数据库的状态,所以我们还需要一个日志管理模块,对操作和错误信息进行记录。数据库中需要支持多用户操作,但每个用户都能操作所有的数据,这是不现实的,所以还需要权限划分模块对数据库用户进行权限管理。当然数据库说到底也只是一款软件,是软件就会有bug,就会出故障,故障不可怕,可怕的是在数据库这种敏感软件下对故障没有特殊的处理方式,导致数据丢失,毕竟数据是无价的,所以数据库应该引入容灾机制,在数据库挂了的时候,对数据进行恢复。还有作为数据库最重要的两个模块,也是现今任何一个数据库都需要考虑的问题——并发和查找效率,所以还需引入索引这两个模块,这就是实现一个最基础的数据库所必需的几大模块。

  • 归纳

    综上对数据库设计模块做一个汇总:
    1.存储模块
    2.程序实例
    2.1存储管理模块
    2.2缓存机制
    2.3SQL解析模块
    2.4日志管理模块
    2.5权限划分模块
    2.6容灾机制
    2.7索引模块
    2.8锁模块

    设计数据库模块.

索引

  • 为什么要使用索引

    要考虑这个问题,首先要从最基础的查找表中数据的过程开始说起。通常我们在查找一个序列中的某一个元素时,用到的最简单的方式就是遍历,数据库也是一样,在一张表中查找某一行数据时,如果不考虑索引的状况下,也会采用一个逐行扫描的方式,只不过数据库通常以块或者页为单位,所以它通常将整个块或者页加载进内存,然后逐块轮询查找到结果并返回。如果数据库中只有少量数据,那么进行全表扫描,速度还是会很快,但是如果在数据量很大的表中,这种方法就不再适用了,在数据量很大的表中,由于逐行扫描代价变大,通常需要避免采用这种逐行扫描的方式进行数据查找,数据库为了使查询变得高效,所以引入了索引这种方式对数据进行查找。

  • 什么样的信息能成为索引

    1.主键、唯一键、普通键

  • 索引的数据结构

    • 二叉查找树

      众所周知,二叉查找树是每个节点最多由两个子树的树结构,而其还有一个特点是,在任意一颗树中,根节点左孩子永远小于根节点,根节点右孩子永远大于根节点,用二叉查找树作为索引,确实可以提高查找效率,其可以使用二分查找将时间复杂度控制在O(lgn),但是二叉查找树有一个显而易见的缺陷,当某种特殊情况(按照某个特定顺序插入树)发生时,二叉查找树将变为下图右侧(线性二叉树)的状况:

      二叉查找树.jpg
      此时二叉查找树查找任意某个元素时,其查找顺序与逐行查找无异,查询时间复杂度又将回到O(n),查询效率无法保持。

    • B-Tree

      B-Tree,平衡多路查找树,如果每个节点,最多有N个孩子,那么这样的树就叫N阶B-Tree, 每个节点中主要包含关键字指向孩子的指针,最多能有几个孩子,取决于节点的容量和数据库的相关配置,通常情况下这个N是很大的。
      B-Tree作为一种数据结构,有如下特征:
      1.根节点至少包含两个孩子
      2.树中每个节点至多含有N个孩子(N>=2)
      3.除根节点和叶节点外,其它每个节点至少有ceil(N/2)个孩子。(ceil表示取上限,例如1.2的上限为2,1.1的上限也为2,非四舍五入
      4.所有叶子节点都位于同一层,即叶子节点的高度都是一样的。
      5.假设每个非终端节点包含n个关键字信息(P0,P1...Pn,k1...kn)

      ( a )ki(i=1..n)为关键字,且关键字按顺序升序排序k(i-1)<ki。
      ( b )关键字的个数必须满足:[ceil(m/2)-1]<=n<=m-1]。
      ( c )非叶子节点的指针:P[1],P[2]...P[M];其中P[1]指向关键字小于K[1]的子树,P[N]指向关键字大于K[N-1]的子树,其它P[i]指向关键字属于(K[i-1],K[i])的子树。

      B-Tree
      遵守上述规则,其目的就是尽量使每个索引块都尽可能多的存储数据,尽可能减少查找次数以提升效率。 举个例子,模拟一下查找过程,以便于理解:假设我们要查询关键字为10的数据,则从根节点出发,10<17,于是通过P1进入其孩子节点,10>8且10<12,于是通过P2进入其孩子节点,最后寻找到10。如果不使用索引,而使用逐行扫描的方式进行查找,则从0开始至少扫描10次才能查找到10号数据,有了索引之后可以看到,查找次数从10变为3,大大提高了查找效率。
      如果这里是二叉查找树,会出现极端情况,使得查找时间复杂度为O(n),而如果是B-Tree,由于上述五个约束,可以让节点通过合并、分裂、上移、下移等操作,使得树高度较二叉查找树小,查找效率显然更高。

    • B+ -Tree(MySQL)

      B+ -Tree是B-Tree的一个变体,其定义基本与B树相同,除了:
      1.非叶子节点的子树指针与关键字个数相同,其表明B+树能存储更多的关键字
      2.非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树。
      3.非叶子节点仅用来做索引,数据到保存在叶子节点中。(B+树的所有检索都是从根部开始,直到搜索到叶子节点结束。)
      4.所有叶子节点均有一个链指针,指向下一个叶子节点。(方便直接在叶子节点直接做范围统计)

      B+Tree.
      B+树相较于B树的优势:
      1.B+树的磁盘读写代价更低。
      2.B+树的查询效率更加稳定。
      3.B+树更有利于对数据库的扫描。

    • Hash

      Hash索引是根据Hash结构的定义,只需要一次运算便可以找到数据所在位置,不像B+树或者B树需要从根结点出发寻找数据,所以Hash索引的查询效率理论上要高于B+树索引,但是MySQL中并没有采用这一种索引,这是由于这种索引除查询效率之外的缺陷是十分明显的。
      1.仅仅只能满足"=","IN",不能使用范围查询。由于其是由Hash运算获取的数据存放位置,每次Hash运算获取的是一个确定的值,且这个值并不与数据本身的大小有关系,所以其并不能满足范围查询。
      2.无法被用来避免数据的排序操作。和1的意思差不多,Hash的索引值是由Hash运算获取的,其索引值与数据本身的大小并无明显关系。
      3.不能利用部分索引键查询。
      4.不能避免表扫描。由于Hash索引会产生Hash冲突,存在Hash冲突的数据会被连接到同一个链表上,当大量数据被连接到相同链表上时,查询某条数据就变成了扫描该链表,时间复杂度并不能保证在O(1)。
      5.遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。

    • BitMap索引

      位图索引,当表中的某个字段只有几种值的时候,例如:性别,此时用位图索引是一个最佳的选择。目前使用位图索引的比较主流的数据库有Oracle数据库。

  • 密集索引和稀疏索引的区别

    1.密集索引文件中的每个搜索码都对应一个索引值,稀疏索引文件只为索引码的某些值建立索引项。
    2.密集索引将数据存储与索引放到了一块,找到索引也就找到了数据,稀疏索引将数据和索引分开存储,索引结构的叶子节点指向数据的对应行。

    • 关于MySQL的MyISAM和InnoDB
      MyISAM不论是主键索引、唯一键索引、还是普通索引,都采用的是稀疏索引,而InnoDB必须有且仅有一个密集索引。
      InnoDB密集索引规则:
      1.若一个主键被定义,该主键则作为密集索引。
      2.若没有主键被定义,该表的第一个唯一非空索引则作为密集索引。
      3.若不满足以上条件,InnoDB内部会生成一个隐藏主键(密集索引)。
      4.非主键索引存储相关键位和其对应的主键值,包含两次查找。
      :InnoDB如果查询条件为主键索引,则只需查询一次,但是辅助索引需要查询两次,先通过辅助索引查询到主键索引,再查询到数据。
      聚簇索引和非聚簇索引
      从上图中可以看到,如果一个索引是聚集索引,则其叶子节点上存放的即是数据本身,而如果一个索引是稀疏索引,叶子节点存放的仅是地址,指向将要查找的数据。
  • 如何定位并优化慢查询SQL

    首先先建立一张表

    CREATE DATABASE sqltest;
    use sqltest;
    create table tb_test(test_id int primary key auto_increment,test_name varchar(1024),test_date datetime,test_desc varchar(1024)
    );
    

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

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

相关文章

spring-boot发送邮件失败 AuthenticationFailedException: 535 Authentication Failed

发送邮件失败&#xff0c;平时一直是好的&#xff0c;突然有天开始失败了&#xff0c;最后是发现邮箱密码失效了。。。 有的邮箱&#xff0c;需要定期更改密码。

互联网广告行业(01)------ 初识了解DSP、SSP、ADX

最近有幸接触到公司的一个实时竞价系统&#xff0c;也算是公司的核心系统之一了&#xff0c;增加了很多新的知识&#xff0c;可能有点乱&#xff0c;先总结一波&#xff1a; 广告行业&#xff0c;先介绍概念 广告主&#xff1a;需要打广告的站点&#xff0c;一般就是卖东西的…

互联网广告行业(02)------OpenRTB(实时竞价)规范解读

RTB&#xff1a;(Real Time Bidding实时竞价)&#xff0c;RTB是一种广告交易的方式 OpenRTB&#xff1a;简单理解就是一个行业规范&#xff0c;是一个为了促进RTB方式广告的标准&#xff0c;有对应的api文档&#xff0c;大家都按照这个规范去传参数&#xff0c;那么发送方和接收…

[go]---从java到go(01)---基础与入门上手

为什么用go&#xff0c;就是为了快速响应并且高并发。 一样的逻辑&#xff0c;用java也能实现&#xff0c;但用go可能就比java快点。 如果你很熟练java了&#xff0c;那么学习go就会很快。 go的社区环境相比java没那么大&#xff0c;但一般问题都足够了。 go是谷歌出品&#xf…

[数据库] --- clickhouse

clickhouse是一个列式数据库&#xff08;系统&#xff09;。 官方文档 官网比较全&#xff0c;但也可以说比较杂&#xff0c;下面就是我个人的一些总结&#xff0c;以及在实际工作中的应用场景。 1.clickhouse适用场景 clickhouse主要适合那种大量数据做分析的场景。 一般数据…

消息队列(5):RocketMQ

介绍 RocketMQ是一款成熟的分布式消息中间件。 由阿里2012年开源&#xff0c;2017年成为Apache顶级项目。 源码是java写的。 高性能&#xff0c;低延迟&#xff0c;高可靠。历经多次双十一大促&#xff0c;整体很稳定。 RocketMQ对比其他mq的优势 对比kafka和Rabbitmq&#…

[错误记录] --- rocketmq批量消费设置参数的问题

rocketmq想支持批量消费&#xff0c;于是便设置以下参数&#xff1a; consumer.setConsumeMessageBatchMaxSize(1000);这样是正确的&#xff0c;但由于业务要求&#xff0c;还想再设置大点&#xff0c;于是设置成这样&#xff1a; consumer.setConsumeMessageBatchMaxSize(10…

阿波罗配置中心(apollo)的个人看法

阿波罗应该是近几年比较火的一个分布式配置中心了&#xff0c;说说我个人的理解&#xff0c;希望对一些人有用吧。 首先从使用者的角度想 我们怎么用配置中心的&#xff1f; 1.得有个页面&#xff0c;能有权限管理&#xff0c;能有创建配置key-value。 在阿波罗中&#xff…

消息队列(4):Kafka

介绍 kafka是一个支持分布式的消息系统&#xff0c;基于发布/订阅模式。 kafka由LinkedIn公司开发&#xff0c;2010年成为Apache顶级项目。 源码是由java写的。 基本概念 1、Broker kafka集群中的每台机器&#xff0c;都叫一个broker. 2、Topic&#xff08;主题&#xff0…

clickhouse的ReplacingMergeTree引擎实战

学习ReplacingMergeTree引擎&#xff0c;首先你得了解clickhouse的MergeTree引擎&#xff0c;因为ReplacingMergeTree引擎是MergeTree引擎的一个扩展版引擎&#xff0c;他拥有和MergeTree一样的功能&#xff0c;同时新增了一个删除相同主键数据的功能。 我们知道&#xff0c;cl…

clickhouse 分片

我们知道mysql数据库如果想做分片&#xff0c;需要使用第三方组件&#xff0c;这是因为mysql在设计之初就没有太多考虑分布式等问题。而clickhouse作为新生代性能之王&#xff0c;分片也是必须的功能。基本上从2015年之后的各种数据库也罢&#xff0c;框架也罢&#xff0c;都开…

[记录] ---阿里云java.io.IOException: Connection reset by peer的问题

项目部署到阿里云&#xff0c;突然报错&#xff0c;频繁的打印堆栈信息&#xff0c;一开始是把堆内存打满导致服务一直重启&#xff0c;调大堆内存后就不影响正常服务了&#xff0c;但还是一直打堆栈&#xff0c;虽说日志会自动清理&#xff0c;但一直打这个信息着实不好看。 最…

实用的java代码生成器,开箱即用(基于mybatisplus的AutoGenerator)

spring-boot工程下&#xff0c;自动生成代码&#xff0c;controller层&#xff0c;service层&#xff0c;mapper层。 根据数据库配置好的表&#xff0c;逆向生成实体类和各层结构 1、引入maven <dependency><groupId>com.baomidou</groupId><artifactId&…

mac/windows 端口占用解决记录

idea启动报错&#xff1a;端口占用 The port may already be in use or the connector may be misconfigured mac端口占用解决 zhangshuaideMacBook-Pro:~ zhangshuai$ lsof -i:8095 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Google 375 zhangshuai 32u IPv6 0x…

skywalking(1) 基于opentracing规范的APM系统

skywalking是&#xff1a; 基于opentracing规范的APM系统 skywalking解决了什么问题&#xff1f; skywalking解决微服务架构下&#xff0c;多服务直接复杂的调用关系 了解dapper&#xff0c;分布式链路追踪系统 dapper又是谷歌论文&#xff0c;各公司又相继模仿。&#xff…

skywalking(4)

Byte Buddy库 统计方法调用时长 1、增强字节码 2、拦截器拦截 类似于spring的aop&#xff0c;只不过skywalking不能用aop&#xff0c;所以用Byte Buddy技术代替 Open Trace 整个trace调用&#xff0c;是由多个span组成的有向无环图&#xff08;就是调用关系图&#xff09;。…

kubernetes(k8s)

应用部署演进过程 我们从上图可以看到&#xff0c;应用越来越看重应用本身了&#xff0c;慢慢的不受物理机的差异&#xff0c;不受操作系统的差异&#xff0c;开发者可以花更多精力去到应用本身。 k8s概念 简单理解&#xff0c;k8s就是传统的云平台上的linux。 kubernetes是…

为什么要用Elasticsearch

概念 Elasticsearch 简称ES&#xff0c;是一个分布式全文检索引擎。 比如github的代码检索就是用了ES&#xff0c;百度也有用ES。 由于Lucene的api相对比较复杂&#xff0c;所以ES其实是对Lucene的封装简化&#xff0c;并且提供了一套比较简单的api文档。 es官网 使用场景 主…

赶紧看一下mysql8.0版本的新特性,你的数据库是不是该升级了

这里写目录标题前言mysql8.0的新特性1、账户安全2、优化器索引2.1、隐藏索引&#xff08;invisible&#xff09;2.2、降序索引2.3、函数索引3、SQL语句增强4、新增数据分析函数5、InnoDB增强5.1、优化了一些元数据文件5.2、将系统表mysql和数据字典表&#xff0c;全部改为InnoD…

ThreadLocal不仅要应付面试,更要真的理解,真的会用

前言 记得我几年前第一次面试的时候&#xff0c;就是被问了这个&#xff0c;记得面试官直接就让我说说ThreadLocal的实现原理以及平时有没有见过哪些地方用到了。 我当时初入职场&#xff0c;还是一个大菜鸟&#xff0c;所以直接就被干蒙了&#xff0c;至今还记忆犹新。 闲来…