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


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

前言

说到数据库这个词,我只能用爱恨交加这个词来形容它。两年前在自己还单纯懵懂的时候进了数据库的课堂,听完数据库的课,觉得这是一门再简单不过的课程,任何一门编程语言都比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),但是二叉查找树有一个显而易见的缺陷,当某种特殊情况(按照某个特定顺序插入树)发生时,二叉查找树将变为下图右侧(线性二叉树)的状况:


      此时二叉查找树查找任意某个元素时,其查找顺序与逐行查找无异,查询时间复杂度又将回到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])的子树。


      遵守上述规则,其目的就是尽量使每个索引块都尽可能多的存储数据,尽可能减少查找次数以提升效率。 举个例子,模拟一下查找过程,以便于理解:假设我们要查询关键字为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+树相较于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.taodudu.cc/news/show-1081675.html

相关文章:

  • java中使用lua脚本
  • java中使用lua操作redis
  • spring-boot发送邮件失败 AuthenticationFailedException: 535 Authentication Failed
  • [go]---从java到go(01)---基础与入门上手
  • [go]---从java到go(02)---一个简单的handler模式的实现
  • [数据库] --- clickhouse
  • 错误记录:expected single matching bean but found 2
  • 消息队列(5):RocketMQ
  • [错误记录] --- clickhouse报错Decimal value is too small
  • [错误记录] --- rocketmq批量消费设置参数的问题
  • rocketmq批量消费
  • 阿波罗配置中心(apollo)的个人看法
  • 消息队列(4):Kafka
  • clickhouse的ReplacingMergeTree引擎实战
  • clickhouse 分片
  • [记录] ---阿里云java.io.IOException: Connection reset by peer的问题
  • 数据库缓存双写一致性的一些个人想法
  • 2020年规划
  • 实用的java代码生成器,开箱即用(基于mybatisplus的AutoGenerator)
  • mac/windows 端口占用解决记录
  • [配置中心] --- consul
  • [java基础] --- java开发,service层是不是一定要写接口
  • 浅谈权限(功能权限数据权限)
  • skywalking(1) 基于opentracing规范的APM系统
  • skywalking(2)
  • skywalking(3)
  • skywalking(4)
  • synchronized锁
  • 讲讲我对比特币和区块链的认知,挖矿不难,挖到难
  • kubernetes(k8s)

[转载] --- 数据库基本知识相关推荐

  1. 【网络转载】Sybase数据库基础知识

    sybase基础知识 http://www.chinaunix.net陈苏文发表于:2002-10-1416:31:50 第一讲Sybase基础知识 一.客户/服务器体系结构 Sybase是一种建立在 ...

  2. Web入门_朽木|学习笔记之第一章-数据库基本知识(1.1-1.7)

    数据库基本知识 目录: 1.1数据库基本知识 1.2关系型数据库基本知识 1.3建表,查询与编辑 1.4结构化查询语言 1.5数据库的种类 1.6网站与数据库 1.7注入与数据库 1.数据库基本知识 ...

  3. 【SAP Hana】X档案:SAP HANA 数据库基础知识

    SAP HANA 数据库基础知识 1.基本规则 (1)注释 (2)标识符 (3)引号 (4)保留字 2.数据类型 (1)日期时间类型 (2)数字类型 (3)字符串类型 (4)二进制类型 (5)大对象类 ...

  4. SQL数据库基础知识-巩固篇一

    SQL数据库基础知识-巩固篇<一>... 首先展示两款我个人很喜欢的数据库-专用于平时个人SQL技术的练习<特点:体积小,好安装和好卸载,功能完全够用了> MySQL-57 D ...

  5. 【转载】Java知识体系最强总结(2020版)

    原文链接.转载 更新于2020-03-14 18:00:00 本人从事Java开发已多年,平时有记录问题解决方案和总结知识点的习惯,整理了一些有关Java的知识体系,这不是最终版,会不定期的更新.也算 ...

  6. MYSQL数据库常用知识整理

    为什么80%的码农都做不了架构师?>>>    MYSQL数据库常用知识整理 什么是MYSQL MYSQL的特性 MYSQL存储引擎的分类以及数据文件的介绍 MYSQL赋权 MYSQ ...

  7. 【转】数据库基本知识:(五)视图应用

    转载出处:http://blog.csdn.net/wsl211511/article/details/44704789 视图是根据预定义的查询建立起来的一个表,它的定义以模式对象的方式存在.同基表一 ...

  8. 计算机二级accesse有哪些内容,二级Access数据库大纲知识要点

    一.数据库基础知识 1.基本概念 1.1 数据库 数据库:指存储在计算机存储设备上.大量结构化的.可共享的相关数据的集合. 信息.消息.信号.数据.知识: 数据库管理系统(DBMS):指帮助用户建立. ...

  9. 软件测试培训分享:做软件测试需要掌握数据库的知识吗?

    最近几年,学习软件测试的同学越来越多,大家对于"做软件测试需要掌握数据库的知识吗?"这个问题都比较关注,那么下面小编就来为大家做下详细的介绍. 软件测试培训分享:做软件测试需要掌握 ...

最新文章

  1. 进程管理3--经典的进程同步问题
  2. html border阴影效果_一篇文章教会你使用html+css3制作炫酷效果
  3. shell编程练习题
  4. HTML+CSS+JS实现 ❤️透明等离子球ui特效❤️
  5. 作者:武永卫(1974-),男,清华大学计算机科学与技术系教授
  6. springdata-jpa 八种查询方法
  7. jquery表单的提交
  8. 教程 海湾主机crt_海湾消防主机JB-QT-GST5000火灾报警控制器(联动型)与crt是怎么连接编公式的...
  9. 小米推送,华为推送,个推,阿里云推送集成(服务端JAVA开发)
  10. 没有基础学习java编程,去培训机构怎么样?
  11. ARM嵌入式开发1:keil软件安装
  12. 数字图像处理与Python实现-边缘检测-高斯差分(DoG)算子边缘检测
  13. #Objective - C - UI-design - 第六天 -UIKit框架-UIScrollView-分屏相册练习(相册缩略图变为浏览到第几张)
  14. 阿里云对象存储上传文件
  15. 过滤器六:url-pattern设置过滤范围
  16. python基本常用语法函数数据结构
  17. 好用的vue瀑布流插件-vue-masonry
  18. el-form表单添加自定义验证
  19. Android 耳机驱动知识
  20. 网易传媒基础架构演进之路

热门文章

  1. 今天pycharm不能正常使用了
  2. pat 甲级 1034. Head of a Gang (30)
  3. MySQL ERROR 1045 (28000): Access denied for user 'root'@'192.168.23.224' (using password: YES)
  4. input框自动填充内容背景颜色为黄色解决方法
  5. 内存对齐分配策略(含位域模式)
  6. Arcgis for javascript不同的状态下自定义鼠标样式
  7. iOS程序UI主线程和定时器相互阻塞的问题
  8. 【分享】关于对象关系映射的理解
  9. 牛客14342 神奇的数字
  10. python- 决策树分类器