数据库的基本原则

数据库的核心原则

  1. 原子性与持久性:原子性(Atomicity)确保一个事务中的所有操作要么全部完成,要么完全不执行,不会出现部分完成的情况。持久性(Durability)则保证一旦事务提交成功,即使发生系统故障,数据的变化也是永久性的。为了实现持久性,可以使用fsync来确保操作系统将数据实际写入到磁盘而不是仅仅保存在缓存中。当数据库崩溃时,需要有一种机制来进行恢复,确保数据的一致性和完整性。

  2. 基于B树的键值存储:这是一种常用的组织和存储数据的方式,特别适合于磁盘上的数据结构。B树是一种平衡树,允许搜索、顺序访问、插入和删除在一个对数时间内完成。通过使用自由列表(free list),可以有效地管理磁盘空间,从而提高性能和效率。

  3. 关系数据库建立在键值存储之上:在这个层次上,表和索引被映射到底层的B树结构。这允许数据库系统以一种高效的方式管理和查询数据。此外,这种类型的数据库通常支持类似SQL的查询语言,它包含了解析器和解释器来处理和优化查询请求。

  4. 事务的并发控制:在多用户环境中,多个事务可能同时尝试访问或修改相同的数据。因此,必须有机制来控制并发事务的执行,以防止数据不一致或其他问题。常见的并发控制技术包括锁定协议(如两阶段锁)、时间戳排序和乐观并发控制等。

理解数据库的核心原则而不是仅仅掌握术语确实是一个更加有效的方法来学习和构建数据库。以下是一些关键的原则,它们构成了数据库系统的基础,并且可以帮助你通过实践来学习如何构建一个简单的数据库。

在这里插入图片描述

通过实践学习:原则而非术语

数据库文献中充满了令人困惑且含义重叠的术语,阅读这些内容时很容易迷失方向。另一方面,费曼曾说过:“我不能构建的东西,我就不理解。” 那么,你能通过阅读有关数据库的内容来构建一个数据库吗?测试一下你的理解吧!

虽然有很多东西需要学习,但并非所有知识都同等重要。构建一个数据库只需要掌握几个基本的原则,因此任何人都可以尝试。

核心原则

  1. 数据模型

    • 数据库需要定义如何组织和存储数据。最基本的数据模型之一是键值对(Key-Value),它简单直观,非常适合初学者理解数据库的基本操作如插入、查找、更新和删除。
  2. 持久性与恢复

    • 数据库必须能够将数据持久化到非易失性存储介质中,例如硬盘。使用写前日志(Write-Ahead Logging, WAL)是一种常见技术,用于确保即使在系统崩溃的情况下也能恢复数据。
  3. 索引结构

    • 为了提高数据检索效率,数据库通常会使用索引。B树或其变体B+树是常见的索引结构,允许快速查找、插入和删除操作。
  4. 事务处理

    • 事务是指一组操作要么全部执行成功,要么完全不执行,从而保证了数据库的一致性和完整性。ACID特性(原子性、一致性、隔离性、持久性)是评估事务处理的重要标准。
  5. 并发控制

    • 当多个用户同时访问数据库时,必须有一种机制来管理这些访问,以避免数据不一致的问题。这可以通过锁机制或者更高级的多版本并发控制(MVCC)实现。

实践建议

  • 动手实践:尝试从头开始编写一个简单的键值存储系统。首先实现基本的PUTGET功能,并考虑如何持久化这些数据。

  • 逐步扩展:一旦有了基础的键值存储,可以考虑添加B树或其他索引来加速查找过程。然后,尝试实现简单的事务支持,比如如何确保在一个操作失败时能够回滚所有相关更改。

  • 模拟故障:测试你的数据库在各种异常情况下的表现,例如突然断电或程序崩溃后能否正确恢复数据。

  • 学习资源:虽然避免过多的专业术语很重要,但了解一些基础概念还是必要的。可以选择那些强调实际构建而非单纯理论讲解的学习材料或教程。

手机使用SQLite而非其他格式(如JSON)存储数据的原因在于,数据库系统提供了更高级的数据完整性和可靠性保证,尤其是在处理异常情况时。以下是关于为何选择SQLite以及如何通过一些技术手段实现数据的持久性和原子性的详细解释。

为什么选择SQLite而不是JSON?

  • 数据完整性和一致性:如果直接使用文件格式(例如JSON),在写入过程中遭遇崩溃可能会导致数据丢失或损坏。这是因为写操作可能只完成了一部分,导致文件处于不一致的状态。
  • 事务支持:SQLite等数据库管理系统(DBMS)提供事务支持,确保数据要么完全更新成功,要么完全不更新(原子性),同时保证一旦事务提交后数据不会丢失(持久性)。

如何通过技术手段解决这些问题

使用fsync实现持久性和原子性
  • 持久性:指的是数据一旦被确认写入后,即使系统发生故障也不会丢失。在操作系统层面,写入操作并不总是立即将数据写入磁盘,而是先存储在缓存中。为了确保数据确实写到了磁盘上,可以使用fsync系统调用。它会强制将所有待处理的数据从缓存刷新到磁盘,并等待该过程完成。

  • 原子性:意味着数据更新要么全部完成,要么完全不进行,不存在中间状态。要实现这一点,一个常见的策略是使用预写日志(Write-Ahead Logging, WAL)。WAL机制会在实际修改数据之前,首先将这些变更记录在一个单独的日志文件中。这样,即便在数据更新过程中发生了崩溃,也可以通过回放日志来恢复到一致的状态。

  • 结合使用fsync和WAL:在执行关键的写操作时,不仅需要调用fsync来确保数据已经物理上写入磁盘,还需要依赖WAL机制来维护数据的原子性。这意味着,在开始任何修改前,先记录变更;然后使用fsync确保这些记录已经被安全地保存;最后才应用这些更改,并再次调用fsync以确保所有更改都已妥善保存。

索引数据结构

通过索引控制延迟和成本

数据库将查询转化为结果,而用户无需了解其内部实现。然而,除了结果本身,延迟和成本(内存、I/O、计算)也是重要的考量因素。这正是分析型(OLAP)和事务型(OLTP)数据库之间的区别所在。

  • OLAP:通常涉及大量数据,并执行聚合或连接操作。由于数据量庞大,索引的使用可能有限甚至完全不存在。
  • OLTP:处理少量数据时依赖索引来快速访问。目标是低延迟和低成本。

需要注意的是,“事务型”这个词并不是指数据库事务,而只是数据库领域的一个有趣术语。


磁盘数据结构的挑战
  1. 原地更新问题
    在磁盘上更新数据时,如果系统崩溃,可能会导致数据处于损坏状态。磁盘并不是“较慢的RAM”,它的行为与内存完全不同。

  2. 随机访问 vs. 顺序访问
    RAM 中的“R”代表“随机”(Random),这意味着内存支持高效的随机访问。而在磁盘上,即使是固态硬盘(SSD),随机访问也比顺序访问慢得多。因此,像二叉树这样的数据结构在磁盘上并不适用,而 B 树和 LSM 树则更适合。

  3. 并发访问
    数据结构的并发访问也是一个重要话题。多个线程或进程同时访问数据时,需要确保一致性并避免竞争条件。


为什么 B 树和 LSM 树适合磁盘?

B 树
  • 特点:B 树是一种平衡树,专为磁盘设计。它的每个节点可以包含多个键值对,从而减少了树的高度,降低了磁盘 I/O 次数。
  • 优点
    • 支持高效的范围查询。
    • 节点大小通常与磁盘块大小一致,优化了顺序读取性能。
LSM 树(Log-Structured Merge Tree)
  • 特点:LSM 树通过将写操作先记录到内存中的缓冲区(MemTable),然后批量写入磁盘的方式来优化写性能。
  • 优点
    • 写操作通常是顺序写入,性能较高。
    • 适合写密集型工作负载(如日志系统)。
  • 缺点
    • 读操作可能需要合并多个文件(SSTables),性能稍差。

OLAP 和 OLTP 的索引策略

  • OLAP

    • 数据量大,查询复杂,索引的作用有限。
    • 常用技术包括列式存储和分布式计算框架(如 Apache Spark)。
  • OLTP

    • 数据量小,但要求低延迟。
    • 索引是核心,常用结构包括 B 树、哈希索引等。

基于键值对的关联数据库

数据库的两层接口

SQL几乎成为了数据库的代名词,但它实际上只是数据库的一个用户界面,并不是数据库的核心。真正重要的是其底层的功能实现。另一种更为简单的接口是键值(KV)存储。通过KV接口,你可以获取、设置和删除单个键值对,更重要的是,可以以排序顺序列出一系列键。KV比SQL简单,因为它处于更低的一层。关系型数据库就是在类似于KV接口的存储引擎之上构建的。

查询语言:解析器与解释器

尽管代码行数较多,但创建一个查询语言的最后一步其实相对简单——无论是解析器还是解释器,都可以通过递归来实现!这个原则几乎可以应用到任何计算机语言的设计上,或者在创建自己的编程语言或领域特定语言(DSL)时使用。(有关更多挑战,请参考我的书《从源代码到机器码》)


关系型数据库如何建立在键值对之上

  1. 底层存储:首先,你需要有一个基础的键值存储系统。这个系统允许你执行基本的操作如GETSETDELETE。此外,支持按键排序并列出键范围是非常重要的,这为后续的关系模型提供了必要的功能支持。

  2. 存储引擎:在KV存储的基础上,构建一个存储引擎。存储引擎负责管理数据的实际存储、索引结构以及事务处理等。对于关系型数据库来说,这意味着需要将表和索引映射到KV存储中的键值对。

  3. 表与索引的映射

    • :每张表可以通过一个唯一的键前缀来标识,表中的每一行则由不同的键表示。例如,键可以设计为<table_name>:<primary_key>的形式。
    • 索引:为了加速查询,可以为常用查询字段建立二级索引。这些索引本身也是KV对,其中键通常是索引字段的值,而值是指向原始记录的引用。
  4. SQL层:在KV存储和存储引擎之上,添加SQL层。这包括SQL语句的解析器和解释器,它们将SQL查询转换为底层KV操作。例如,一个简单的SELECT查询可能被转化为一系列的KV查找操作。

  5. 递归实现解析器和解释器:虽然听起来复杂,但是利用递归技术,可以有效地构建出SQL查询的解析器和解释器。递归使得处理嵌套查询和复杂语法变得更加直观和易于管理。

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

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

相关文章

Java设计模式实战:装饰模式在星巴克咖啡系统中的应用

一、装饰模式简介 装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种模式创建了一个装饰类&#xff0c;用来包装原有的类&#xff0c;并在保持类方法签名完整性的前…

使用MPI-IO并行读写HDF5文件

使用MPI-IO并行读写HDF5文件 HDF5支持通过MPI-IO进行并行读写&#xff0c;这对于大规模科学计算应用非常重要。下面我将提供C和Fortran的示例程序&#xff0c;展示如何使用MPI-IO并行读写HDF5文件。 准备工作 在使用MPI-IO的HDF5之前&#xff0c;需要确保: HDF5库编译时启用…

七、自动化概念篇

自动化测试概念 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的过程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。在此过程中&#xff0c;为了节省人…

redis cluster 的通信机制

Redis Cluster 的通信机制是其分布式架构的核心&#xff0c;基于 Gossip 协议 和 Cluster Bus 实现节点间状态同步与数据协调。以下是其通信机制的核心要点&#xff1a; 二进制协议&#xff1a;数据以字节流形式编码&#xff08;如Protobuf、Thrift、MQTT、Gossip&#xff09;。…

CTF web入门之文件上传

知识点 产生文件上传漏洞的原因 原因: 对于上传文件的后缀名(扩展名)没有做较为严格的限制 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件) 对于web server对于上传…

PhotoShop学习09

1.弯曲钢笔工具 PhotoShop提供了弯曲钢笔工具可以直观地创建路径&#xff0c;只需要对分段推拉就能够进行修改。弯曲港币工具位于工具面板中的钢笔工具里&#xff0c;它的快捷键为P。 在使用前&#xff0c;可以把填充和描边选为空颜色&#xff0c;并打开路径选项&#xff0c;勾…

tsconfig.json配置不生效

说明一下我遇到的问题&#xff0c;这是我的配置文件代码的 {"compilerOptions": {"module": "none","target": "ES5","outFile": "./dist/bundle.js"} } 和我想象不同的是&#xff0c;我编译成 js 没…

源代码加密之零日攻击

# SDC沙盒&#xff1a;有效防御零日攻击的多层防护体系 在当今复杂多变的网络安全环境中&#xff0c;零日攻击已成为企业面临的重大威胁之一。零日攻击利用尚未被公众发现或尚未被软件供应商修复的漏洞进行攻击&#xff0c;具有极高的隐蔽性和破坏性。SDC沙盒作为一种先进的数…

记录一次TDSQL网关夯住故障

环境信息&#xff1a; TDSQL-MySQL同城双中心集群&#xff0c;集中式实例&#xff0c;一主三副本&#xff0c;每个中心两个db副本&#xff0c;每个中心一个VIP&#xff0c;V每个IP通过硬件做负载均衡指向该中心两个proxy&#xff0c;操作系统为麒麟v10 arm。 故障描述&#xf…

代码随想录八股训练营完结总结

&#xff01; 40天的训练营&#xff0c;我总结了自己完整的八股文&#xff0c;后续在面试过程中可以补充 很感谢这次训练营&#xff0c;真的高频&#xff0c;在面试中能击中60%以上&#xff0c;剩下的就靠平时的积累了。 感谢训练营的小伙伴&#xff0c;很多次想偷懒&#x…

VS Code 的 .S 汇编文件里面的注释不显示绿色

1. 确认文件语言模式 打开 .S 文件后&#xff0c;查看 VS Code 右下角的状态栏&#xff0c;确认当前文件的识别模式&#xff08;如 Assembly、Plain Text 等&#xff09;。如果显示为 Plain Text 或其他非汇编模式&#xff1a; 点击状态栏中的语言模式&#xff08;如 Plain Te…

iphone各个机型尺寸

以下是苹果&#xff08;Apple&#xff09;历代 iPhone 机型 的屏幕尺寸、分辨率及其他关键参数汇总&#xff08;截至 2023年10月&#xff0c;数据基于官方发布信息&#xff09;&#xff1a; 一、标准屏 iPhone&#xff08;非Pro系列&#xff09; 机型屏幕尺寸&#xff08;英寸…

VSCode写java时常用的快捷键

首先得先安好java插件 1、获取返回值 这里是和idea一样的快捷键的&#xff0c;都是xxxx.var 比如现在我new一个对象 就输入 new MbDo().var // 点击回车即可变成下面的// MbDo mbDo new MbDo()//以此类推get方法也可获取 mbDo.getMc().var // 点击回车即可变成下面的 // St…

相机内外参

文章目录 相机内参相机外参 相机的内外参是相机标定过程中确定的重要参数&#xff0c;用于建立图像像素坐标与实际世界坐标之间的关系。 相机内参 定义&#xff1a;相机内参是描述相机内部光学和几何特性的参数&#xff0c;主要包括焦距、主点坐标、像素尺度因子以及畸变系数等…

【视频目标分割论文集】Efficient Track Anything0000

github 摘要 视频对象分割和追踪任意目标领域出现了强大的工具——分割任意模型 2&#xff08;SAM 2&#xff09;。SAM 2 实现令人印象深刻的视频对象分割性能的关键组成部分包括用于帧特征提取的大型多阶段图像编码器&#xff0c;以及存储过去帧记忆上下文以辅助当前帧分割的…

CSS学习02 动态列数表格开发,解决多组数据布局与边框重合问题

概要 在前端开发中&#xff0c;表格常用于展示结构化数据。当数据组的字段数量不统一时&#xff08;如有的行包含 3 组数据&#xff0c;有的行包含 2 组或 1 组&#xff09;&#xff0c;传统固定列数的表格会出现结构错位、边框重合等问题。本文通过 HTML/CSS 规范方法&#x…

Spark-core编程总结

1.reduce‌ 功能‌&#xff1a;聚集RDD中的所有元素&#xff0c;先聚合分区内数据&#xff0c;再聚合分区间数据。 示例‌&#xff1a;rdd.reduce(__) 将RDD中的所有整数相加。 2.collect‌ 功能‌&#xff1a;在驱动程序中&#xff0c;以数组Array的形式返回数据集的所有元…

处理Long类型长度超长导致前端精度丢失问题

1&#xff0c;问题场景 后端返回的Long类型的数据&#xff0c;超10000000000000000&#xff0c;前端处理的时候&#xff0c;数据被截断了。比如tchId: 11073477511443988481&#xff0c; 前端根据tchId获取下一环节信息的时候&#xff0c;传的tchId变成了11073477511443988400&…

ONVIF/RTSP/RTMP协议EasyCVR视频汇聚平台RTMP协议配置全攻略 | 直播推流实战教程

在现代化的视频管理和应急指挥系统中&#xff0c;RTMP协议作为一种高效的视频流传输方式&#xff0c;正变得越来越重要。无论是安防监控、应急指挥&#xff0c;还是物联网视频融合&#xff0c;掌握RTMP协议的接入和配置方法&#xff0c;都是提升系统性能和效率的关键一步。 今天…

安徽京准:GPS北斗卫星时空信号安全防护装置(授时)介绍

安徽京准&#xff1a;GPS北斗卫星时空信号安全防护装置&#xff08;授时&#xff09;介绍 1、主要特点 ★信号加固功能&#xff1a; GPS/BDS单系统信号拒止情况下&#xff08;包含受到GPS L1欺骗干扰、GPS L1压制干扰、BDS B1欺骗干扰、BDS B1压制干扰&#xff09;&#xff…