您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

我在Github上发现了一个好东西

时间:2022-11-01 10:32:26  来源:  作者:小小怪下士的架构攻略

作为一个天天都在CRUD的程序员,你有没有想过,数据库是如何工作的?

我猜,你曾经无数次的翻开讲数据库的书籍和文章,但总是看着看着就被劝退,太多的专业术语把人头都搞大了。

等等,看这画风,今天是要卖课的节奏啊!

NO!绝不卖课,请放心阅读。

一直以来,我都很想深入学习一下数据库。我这个人学东西,如果只知其然而不知其所以然是非常难受的,啥都想去了解下背后的原理,学编程语言是这样,学操作系统也是这样。数据库这个东西天天都在用,所以学习一下背后的原理也是非常实用和有必要的。

但无论是哪本书、哪个视频教程,一打开就被无数的专业术语淹没,太多概念淹没了数据库最本质最核心的东西。

所以今天,让我们从一个最最最简单的模型开始,揭开数据库神秘的一角。

对我们使用者而言,数据库就像是一个黑盒子,你可以往它里面写入数据,也可以从它里面读出数据。

 

让我们暂时抛却SQL、网络连接、数据库等等概念,就来看这个最基本的需求:如果我们来实现一个可以对外提供读写数据的黑盒子,该怎么做?

假设我们的黑盒子很简单,里面只有一张表:user_info,用来存储用户信息。

表里面也很简单,只有三个字段,分别记录用户的ID、姓名和手机号。

user_id(uint32)
name(char[8])
phone(char[20])

我们可以用一个简单的结构体(或者一个class)来表示一条数据:

struct DataRecord{
  uint32 user_id;
  char name[8];
  char phone[20];
};

user_id是一个uint32类型,占4个字节,name占8个字节,phone占20个字节,加起来一条数据总共占32个字节。

我们选择用一个文件来存储这些数据,存储非常简单,只需要一条一条的码在一起就行了,就像这样:

 

数据存储方式有了,接下来就是如何来读写了,我们来提供两个函数,分别来插入(insert)和查询(select)数据:

// 伪代码
void insert(Table* table, DataRecord record) {
  fp = open(table->file_name);
  fseek(fp, FILE_END);
  write(fp, sizeof(DataRecord));
  close(fp);
}

插入很简单,直接打开表对应的数据文件,然后把文件指针移动到文件尾部,接着追加数据,最后关闭文件,大功告成。这和把大象关进冰箱的步骤是一样一样的。

接下来是查询,我们提供一个可以通过id来查询用户的函数:

// 伪代码
DataRecord select(uint32 user_id) {

  DataRecord result;
  fp = open(table->file_name);
  
  while (1) {
    if (feof(fp)) 
      break;
      
    DataRecord record;
    read(fp, &record, sizeof(DataRecord));
    if (record.user_id == user_id) {
      result = record;
      break;
    }
  }
  
  close(fp);
  
  return result;
}

查询也很简单,我们打开文件,一条一条读取数据,然后比较用户id和给定的参数是否相同,直到找到符合条件的数据返回。

好了,以上,我们就实现了一个最最最基础的黑盒子:它里面有一张表,然后可以往里面写数据,从里面查数据。

现在来思考一下:

如果我们写了很多数据进去,比如几十万条,我们要查一个指定id的数据,要按照这样一条条比对,那不得等到猴年马月去了?

为什么要一条条比对呢?是因为我们的数据全都是一条一条码在一起的,完全没有顺序,所以要查询,只能这样一条条检查——全表扫描

如果我们的数据是有顺序的呢?

假如我们插入数据的时候,是按照id从小到大排列着,这样我们就能用二分法快速找到指定id的数据了。

 

看上面这张图,假设我们要查找id为9的数据,我们可以读取第一条数据的id是1,就知道id为9的数据肯定在它后面。然后再读取最后一条数据id是12,就知道id为9的数据肯定在它前面,然后选择中间的数据读取,如此二分查找,很快就能锁定目标,不用每条数据都读取了。

因为每条数据都是32个字节,所以可以非常方便定位任意一条数据的位置:第n条数据的位置在32*(n-1)偏移处。

通过改变数据的存储组织形式,我们可以把数据查找的时间复杂度从O(N)下降到O(LogN)。

但如此一来,查找是变快了,但插入就麻烦了。以前的时候,我们直接把数据塞到文件最后就拍拍屁股走人了。但现在不行了,我们得把数据按照顺序,插入到合适的位置。

最麻烦的是,我们的数据是一条一条挨个码在一起的,如果中间某个位置要插入数据,就得把那个位置及其以后的数据通通往后移动,这就涉及到大量的数据复制移动,开销非常大。

要是每来一条insert操作就数据大量迁徙,那不得累得半死?

(其实不止插入,删除数据delete也同样如此麻烦)

就没有一种办法,可以同时插入快,查询也快吗?


仔细思考一下,前面我们把数据按顺序一条一条码在一起,查起来为什么快?

是因为做了排序以后,数据的存储位置有一条隐含的信息:如果id比我们要找的小,那我们要找的肯定在它后面;反之,如果id比我们要找的大,那我们要找的肯定在它前面。

之所以有这个规律,是因为我们按id的大小进行了排序存储。

那如果现在回到最开始的那种方式,不排序了,还是一条一条顺序来写入,就没有这个信息了。

但如果,我们在每条数据记录中增加一些额外的信息,用来指示id比它小的在哪里,id比它大的又在哪里,是不是就能顺着这些额外的信息“顺藤摸瓜”找到你要找的数据呢?

或许,聪明的你已经看出来了,这是按照“二叉树”的形式在记录数据位置信息。

 

但实际上,二叉树也才两个分叉,如果数据量很大的话,这棵树就会很高很瘦。

而每一次走入一个分支,就对应着一次文件I/O,所以在实际使用中,不会使用二叉树,而是使用开了非常多个叉的树——B树或者B+树。

 

如果用B树或者B+树来将文件中的数据在逻辑上组织起来,要查找数据就会快得多。

用id来查找数据问题解决了,但如果要用name来查找又该怎么办呢?

想一想,如果另外有一个文件,记录了每个name和这个name对应的数据记录在文件中的偏移位置,就像这样:

user_id数据位置(偏移)xuanyuan0shuAIdi31april63dibingfa95

有了这个东西,是不是就简单很多了?只需要在这里搜一遍,拿到数据的位置,然后打开文件,定位到对应的偏移,一下就读出来了。

我们可以另外准备一个文件,同样使用B树或者B+树的形式来组织上面表格中的对应关系。

聪明的你可能已经看出来了,这玩意儿其实就是索引。当然实际中的数据库系统的索引实现或多或少有一些差别,但道理是通用的。

 

原文链接:
https://mp.weixin.qq.com/s/wUwJ4sPapE74AbOE2j5hMw



Tags:Github   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
GitHub顶流"Web OS"——运行于浏览器的桌面操作系统、用户超100万、原生jQuery和JS编写
Puter 是近日在 GitHub 上最受欢迎的一款开源项目,正式开源还没到一周 ——star 数就已接近 7k。作者表示这个项目已开发 3 年,并获得了超过 100 万用户。根据介绍,P...【详细内容】
2024-03-10  Search: Github  点击:(25)  评论:(0)  加入收藏
基于GitHub App 深度讲解Kotlin高级特性与框架设计
基于GitHub App 深度讲解Kotlin高级特性与框架设计GitHub App 是 GitHub 平台上的一种特殊类型的应用程序,它允许开发者通过 GitHub API 与 GitHub 上的仓库和组织进行交互...【详细内容】
2023-11-28  Search: Github  点击:(199)  评论:(0)  加入收藏
GitHub:程序员正积极使用 AI 编程、JavaScript 语言依然最流行
IT之家 11 月 20 日消息,GitHub 发布了 2023 年度 Octoverse 开源状态报告,其中主要强调了 AI 在开发过程中的作用,并围绕云和 Git 的开源活动展开。官方介绍称,今年的三大趋势...【详细内容】
2023-11-20  Search: Github  点击:(171)  评论:(0)  加入收藏
Git新手如何上传项目代码到GitHub并完成后续的代码更新?
国内对于个人站长的发展空间限制越来越多,首先是百度主推自家产品,现在权重最高的似乎就是百家号了,其次是腾讯云、阿里云这些提供IDC大厂提供的云端服务产品也很少有针对个人...【详细内容】
2023-11-15  Search: Github  点击:(243)  评论:(0)  加入收藏
如何在GitHub上存储源码并保持同步
GitHub是一个广泛使用的基于云的代码托管平台,它为开发者提供了一个便捷的方式来存储、管理和共享他们的源代码。通过GitHub,开发者可以轻松地与团队成员合作,跟踪代码更改,并保...【详细内容】
2023-11-15  Search: Github  点击:(232)  评论:(0)  加入收藏
GitHub在大会上发布的十大AI更新!
作者 | Tasmia 策划 | 言征出品 | 51CTO技术栈(微信号:blog51cto)GitHub的母公司微软在生成人工智能业务方面取得了巨大增长,该公司首席执行官萨蒂亚·纳德拉告诉华尔街,该...【详细内容】
2023-11-13  Search: Github  点击:(226)  评论:(0)  加入收藏
重塑 GitHub、颠覆程序开发:GitHub Universe 2023 发布重大更新
编译 | 核子可乐、TinaGitHub 的东家微软看到了生成式 AI 业务的大幅增长,其首席执行官萨蒂亚·纳德拉 (Satya Nadella) 告诉华尔街,GitHub Copilot 软件的付费客户在第...【详细内容】
2023-11-10  Search: Github  点击:(221)  评论:(0)  加入收藏
GitHub黑市曝光,高档刷星6元一颗,最奇葩开源项目97%都是刷的
梦晨 克雷西 发自 凹非寺量子位 | 公众号 QbitAI在黑市买GitHub星星多少钱?最贵的高达6元一颗。有创业者Yassin Eldeeeb自掏腰包测试了一把。他足足花20欧元(约156人民币),只买...【详细内容】
2023-11-05  Search: Github  点击:(60)  评论:(0)  加入收藏
AI编程,详细比较GitHub Copilot对比Amazon CodeWhisperer
1、简介GitHub Copilot和Amazon CodeWhisperer是采用人工智能技术驱动的编码助手,它们将自动完成编码功能提升到一个全新的水平。在最佳状态下,它们可以根据开发者提供的简短...【详细内容】
2023-11-01  Search: Github  点击:(225)  评论:(0)  加入收藏
大模型无法替代码农!普林斯顿芝大惊人发现:GPT-4解决GitHub编程问题成功率为0
Stack Overflow,已经被ChatGPT创飞了!因为码农大量涌向ChatGPT、Github Copilot,Stack Overflow今天不得已宣布裁员100多人,几乎占员工人数的1/3。所以,ChatGPT这类AI编码工具,真...【详细内容】
2023-10-17  Search: Github  点击:(284)  评论:(0)  加入收藏
▌简易百科推荐
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(2)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(7)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
站内最新
站内热门
站内头条