当前位置: 首页 > 科技观察

只需几行代码即可创建一个数据库!

时间:2023-03-14 20:20:15 科技观察

本文转载自微信公众号《小菜学编程》,作者fasionchan。转载本文请联系小彩雪编程公众号。最近重读了?这本书,看到了第三章《数据存储与检索》,主要讲了数据库内部的索引技术。本质上,数据库主要做两件事:当你给它数据时,它帮你保存数据(存储);当您查询数据时,它会帮助您检索数据(retrieval);看似简单,背后却大有玄机。那么,如何在数据库中存储数据呢?你如何检索数据?您可能会有这样的疑问:作为开发人员,为什么我需要知道数据库是如何工作的?显然,我们不会从头开始,推出一个存储引擎。但是,由于市场上的数据库产品太多,我们需要选择最适合自己应用场景的一款。为了提高性能,我们还需要根据应用负载特点对数据库进行调优。因此,你必须对数据库的底层技术有一定的了解,知道它在幕后做了什么。根据应用负载特点,数据库大致可以分为两种类型:一种是面向在线交易业务的,多采用行存储;另一种是离线分析业务,多采用列存;为了提高检索速度,索引必不可少。不同的存储引擎使用的索引技术不尽相同,大致可以分为两种:日志结构的,比如LSM树;面向页面的存储引擎(page-oriented),比如B-tree;概念,作者用几行Shell代码写了一个玩具数据库:#!/bin/bashdb_set(){echo"$1,$2">>database}db_get(){grep"^$1,"database|sed-e"s/^$1,//"|tail-n1}这两个短shell函数实现了一个KV风格的数据库引擎。麻雀虽小,五脏俱全!它提供了两个基本操作:db_set,保存键值对数据,即将键值添加到以逗号分隔的名为database的数据文件中;db_get,按键取出对应的数据,即从数据库文件中过滤出包含指定key的最后一行数据;这个toy数据库可以这样使用,比如保存键值对数据:fasion@SmartPro[~]?db_set1fasionchan.comfasion@SmartPro[~]?db_set2fasion@SmartPro[~]?db_set3Python源码分析数据最后保存在数据库文件中,每个key-valuepair为一行,格式大致是这样的:fasion@SmartPro[~]?catdatabase1,fasionchan.com2,Xiaocaixueprogramming3,Python源码分析可以这样查询数据:fasion@SmartPro[~]?db_get1fasionchan.comfasion@SmartPro[~]?db_get3Python源码分析修改数据时,新记录追加到数据库文件末尾,旧数据不会被删除:fasion@SmartPro[~]?db_set3Python源码深度解析fasion@SmartPro[~]?catdatabase1,fasionchan.com2,小菜学习编程3,Python源码解析3,Python源码深度解析所以我们查询数据的时候db_set需要执行tail命令在完结,以最新为准:fasion@SmartPro[~]?db_get3Python源码深度解析这个玩具看起来很有趣,但是它的性能呢?db_set操作的性能非常好,因为它只是将数据记录附加到数据库文件的末尾,这通常很快。与db_set类似,很多数据库也有一个append-only数据文件,一般称为操作日志。虽然实际的数据库需要考虑更多的因素,包括并发控制、磁盘空间重用、错误处理等,但是基本原理是一样的。但是,如果数据库中有大量数据,db_get操作的性能可能会很差。因为每次查询一个key,db_get都要扫描整个数据库文件!这是一个典型的操作,数据库记录数增加一倍,查询开销也会增加一倍!不太好!为了在数据库中快速检索数据,我们需要另一种数据结构:索引。索引是一些额外的元数据(metadata),就像路标一样,可以帮助我们快速定位数据。如果你的数据有多个查询条件,你可能需要建立多个索引。索引可以加快查询速度,但也会带来额外的开销,尤其是写操作。任何索引都会降低写入性能,因为每次写入数据时,都必须更新索引。因此,每个存储系统都需要根据实际情况做出取舍:选择好的索引可以加快查询速度;索引肯定会降低写入性能;因此,数据库通常不会默认建立索引,需要开发者或数据库管理员自行选择。要想以最小的成本换取最大的收益,不仅需要对应用的查询方式有准确的把握,还需要对数据库内部的索引技术有一定的了解。