h2database源码解析-表和索引

news2024/10/2 18:20:16

目录

  • 索引
    • MVPrimaryIndex
    • MVDelegateIndex
    • MVSecondaryIndex
    • 索引更新

h2使用类MVTable表示数据库表,h2的表数据是基于主键排列的,这种表也叫做主键索引表。这也就意味着表必须有主键,如果没有主键,h2会自动生成一个主键_ROWID_,字段类型为long型。另外,如果定义表的时候主键设置为了非数字类型或者主键设置了多个字段,h2也是自动生成主键_ROWID_。当有了字段_ROWID_之后,表的数据便是根据_ROWID_组织,也就是说代表表的B+树上的key是_ROWID_,value是行记录。
当向表中插入数据时,h2使用如下代码设置B+树上的key:

		//mainIndexColumn表示主键字段在表中的位置,这个是按照定义表时字段顺序来的,
		//如果定义表时第一个字段是主键,那么mainIndexColumn为1
		//当主键是非数字类型或者有多个字段,mainIndexColumn =SearchRow.ROWID_INDEX
        if (mainIndexColumn == SearchRow.ROWID_INDEX) {
            if (row.getKey() == 0) {
            	//lastKey类型为AtomicLong,lastKey初始值为0
                row.setKey(lastKey.incrementAndGet());
            }
        } else {
            long c = row.getValue(mainIndexColumn).getLong();
            row.setKey(c);
        }

假设新建表USER_INF_1:

CREATE TABLE USER_INF_1(
	name VARCHAR(100) not null primary key, 
	sex VARCHAR(2)
)

向该表中插入如下记录:

INSERT INTO USER_INF_1 VALUES('Tom', '男');

插入记录后,USER_INF_1的B+树结构为:
请添加图片描述

假设新建表USER_INF_2:

CREATE TABLE USER_INF_2(
	id INTEGER not null primary key,
	name VARCHAR(100) not null, 
	sex VARCHAR(2)
)

向该表中插入如下记录:

INSERT INTO USER_INF_2 VALUES(10,'Tom', '男');

插入记录后,USER_INF_2的B+树结构为:
请添加图片描述

索引

索引一般分为主键索引和二级索引,二级索引也叫作辅助索引或者非主键索引。
在h2中,二级索引使用类MVSecondaryIndex表示。主键索引比较复杂:

  1. 如果定义了主键为数字类型且只有一个字段,那么h2会创建两个索引:MVPrimaryIndex和MVDelegateIndex;
  2. 除了第一种情况外,定义表之后h2会创建MVPrimaryIndex,如果还定义了主键,h2再创建一个MVSecondaryIndex表示主键索引。

下面分别介绍这三个类的关系。

MVPrimaryIndex

大家都知道h2的表数据是根据主键组织的,所以h2定义了MVPrimaryIndex类用来表示主键索引。虽说MVTable对象表示数据库表,但是表数据都是存储在MVPrimaryIndex里面,表数据都是由MVPrimaryIndex来管理和维护的。MVPrimaryIndex底层使用B+树将数据存储在磁盘上。
h2的每个数据库对象都有一个名字,MVPrimaryIndex对象叫做“TABLE_NAME_DATA”,表示这是某个表的数据。
上面表USER_INF_1和USER_INF_2的数据存储结构图其实就是MVPrimaryIndex。

MVDelegateIndex

MVDelegateIndex从名字上可以看出这是一个代理索引。它的使用场景比较简单,如果表定义了主键索引,索引中字段只有一个,并且是数字类型的,那么h2会再创建一个MVDelegateIndex对象,该对象有一个属性mainIndex指向了MVPrimaryIndex对象。调用MVDelegateIndex的方法,其实都是调用MVPrimaryIndex的方法,比如MVDelegateIndex的下面两个方法:

    @Override
    public long getRowCount(SessionLocal session) {
        return mainIndex.getRowCount(session);
    }

    @Override
    public long getRowCountApproximation(SessionLocal session) {
        return mainIndex.getRowCountApproximation(session);
    }

不过,像向表里面插入数据这种操作,MVDelegateIndex的方法是空的,因为MVPrimaryIndex已经插入过了:

    @Override
    public void add(SessionLocal session, Row row) {
        // nothing to do
    }

MVSecondaryIndex

二级索引使用MVSecondaryIndex表示。如果表的主键索引有多个字段或者不是数字类型的,那么尽管定义了主键索引,h2也是把它当做二级索引使用,因此也是创建一个MVSecondaryIndex对象,只不过这种MVSecondaryIndex对象的名字叫做“PRIMARY_KEY_X”(最后的X表示序号),表示这是某个表的主键索引。如果是二级索引,MVSecondaryIndex对象的名字就是我们定义的索引名字。

假设定义了USER_INF_3表:

CREATE TABLE USER_INF_3(
	id INTEGER not null, 
	name VARCHAR(100) not null, 
	sex VARCHAR(2)
);
alter table USER_INF_3 add primary key(id,name);
CREATE index idx_name on USER_INF_3(name);

执行上述语句后,可以看到USER_INF_3有三个索引对象:
请添加图片描述

上图的三个索引分别是存储表数据的MVPrimaryIndex对象,主键索引MVSecondaryIndex对象,二级索引idx_name MVSecondaryIndex对象。
假设对USER_INF_3表执行了下面的SQL语句:

INSERT INTO USER_INF_3 VALUES(10,'Tom', '男');

那么三个索引的B+树结构为:
请添加图片描述

索引更新

当表数据发生增删改时,索引也要跟着变化。
在MVTable对象中有一个属性indexes:

	private final ArrayList<Index> indexes = Utils.newSmallArrayList();

属性indexes保存了该表的所有索引,也就是前三个小节介绍的三个类的索引对象。
每当发生增删改时,MVTable都会遍历属性indexes,调用索引对象的update方法和add方法,其中update方法用于处理数据的删改,add方法用于处理数据的增加。

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

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

相关文章

在Linux和Windows上编译datax-web-ui源码

记录&#xff1a;375场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;使用apache-maven-3.8.7安装编译datax-web-ui源码。在Windows上操作系统上&#xff0c;使用apache-maven-3.8.7编译datax-web-ui源码。版本&#xff1a;JDK 1.8 node-v14.17.3 npm-6.14.13datax-web-ui开…

江苏五年制专转本应该复习几轮?

五年制专转本应该复习几轮&#xff1f; 据调查统计&#xff1a;2022年专转本17%的考生复习三轮及以上&#xff0c;23%的考生复习了两轮。这两类的考生录取率高至85%。可见复习轮数多&#xff0c;专转本上岸的概率也大。综合多方因素&#xff0c;建议同学们专转本复习四轮&#…

pointpillars Paper学习总结

Pointpillar Paper PointPillars提出了一种新的点云编码方式和3D转2D的方法&#xff0c;用2D卷积的方式实现目标检测而没有采用耗时的3D卷积&#xff0c;在速度和精度上达到了很好的平衡&#xff0c;其速度快、精度高、易于部署的特点使得其在工业界得到了广泛的应用。 处理思…

JavaWeb--JDBC

JDBC1 JDBC概述1.1 JDBC概念1.2 JDBC本质1.3 JDBC好处2 JDBC快速入门2.1 编写代码步骤2.2 具体操作3 JDBC API详解3.1 DriverManager3.2 Connection3.2.1 获取执行对象3.2.2 事务管理3.3 Statement3.3.1 概述3.3.2 代码实现3.4 ResultSet3.4.1 概述3.4.2 代码实现3.5 案例3.6 P…

2.Java基础【Java面试第三季】

2.Java基础【Java面试第三季】前言推荐2.Java基础01_字符串常量Java内部加载-上58同城的java字符串常量池面试code讲解intern()方法---源码解释02_字符串常量Java内部加载-下whyOpenJDK8底层源码说明递推步骤总结考查点03_闲聊力扣算法第一题字节跳动两数求和题目说明面试题解法…

rt-thread 移植调试记录

rt-thread 移植调试记录 记录rt-thread移植的过程。这里移植仅仅是利用rt-thread源码目录已经移植好的文件&#xff0c;组建自己的工程&#xff0c;不需要自己编写汇编完成底层移植。 1. 搭建基础工程 这里使用的是正点原子的潘多拉开发板&#xff0c;MCU为stm32l475。需要先…

【c++】类和对象:让你明白“面向一个对象有多重要”:构造函数,析构函数,拷贝构造函数的深入学习

文章目录 什么是面向对象&#xff1f;一&#xff1a;类是什么&#xff1f; 1.类的访问限定符 2.封装 3.类的实例化 4.this指针二&#xff1a;类的6个默认成员函数 1.构造函数 2.析构函数 3.拷贝构造函数什么是面向对象&#xff1f; c语言是面向…

window系统中安装Jupyter Notebook方法记录

1.初步感受Jupyter Notebook Jupyter Notebook 官网地址&#xff1a;Jupyter Notebook Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xf…

Java体系最强干货分享—挑战40天准备Java面试,最快拿到offer!

如何准备java面试&#xff0c;顺利上岸大厂java岗位&#xff1f; 主攻Java的人越来越多&#xff0c;导致行业越来越卷&#xff0c;最开始敲个“hello world”都能进大厂&#xff0c;现在&#xff0c;八股、全家桶、算法等等面试题横行&#xff0c;卷到极致&#xff01;就拿今年…

聊聊什么是架构,你理解对了吗?

什么是架构?软件有架构?建筑也有架构?它们有什么相同点和不同点? 下面咱们就介绍一下,容易混淆的几个概念 一、系统与子系统 系统 泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是 “总体”、“整体”或“联盟” 子系…

Java基础常见面试题(二)

面向对象基础 面向对象和面向过程的区别 面向过程 优点&#xff1a; 性能比面向对象高&#xff0c;因为类调用时需要实例化&#xff0c;开销比较大&#xff0c;比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发&#xff0c;性能是最重要的因素。 缺点…

如何做迭代规划

敏捷开发中的迭代规划如同使用需求漏斗&#xff0c;对各方需求定期进行优先级排序并层层拆解或合并&#xff0c;最终把高优先级且细粒度的需求从漏斗进入到研发团队&#xff0c;确保研发团队做对的事&#xff08;Do Right Things&#xff09;&#xff0c;避免团队跑偏方向或进度…

Netty之EventLoopGroup详解

目录 目标 Netty版本 Netty官方API NioEventLoopGroup和DefaultEventLoop的区别 EventLoopGroup实现对内部EventLoop的轮询 EventLoop对普通任务和定时任务的实现 执行普通任务 执行定时任务 划分EventLoopGroup职责 简言 实现 指定EventLoopGroup操作ChannelHandl…

手机上怎么在线生成gif?1分钟教你手机图片合成gif

怎样通过手机实现在线制作GIF图片的操作呢&#xff1f;接下来&#xff0c;给大家分享两招gif制作&#xff08;https://www.gif.cn/&#xff09;小窍门-【GIF中文网】不需要下载任何软件&#xff0c;小白也能轻松上手。支持原画质导出&#xff0c;图片无损处理。一起来看看具体步…

前端教学视频分享(视频内容与市场时刻保持紧密相连,火热更新中。。。)

⚠️获取公众号 本次要想大家推荐一下本人的公众号&#xff0c;在微信中搜索公众号 李帅豪在对话框中输入前端视频四个字即可立即获取所有视频&#xff0c;不收费无广告&#xff01;&#xff01;&#xff01; 本公众号收集了近两年来前端最新最优秀的学习视频&#xff0c;涵盖…

大数据技术架构(组件)30——Spark:Optimize--->Submit

2.1.9、Optimize--->Submit调优工作主要从CPU、内存、网络开销和IO四方面入手2.1.9.0、Spark On Yarn2.1.9.0.1、Jar包管理及本地性调优spark.yarn.jars :将jar包放到hdfs上&#xff0c;避免每次driver启动的时候都要进行jar包的分发。yarn.nodemanager.localizer.cache.cle…

ChatGPT告诉你智能制造

ChatGPT自上线以来&#xff0c;几乎得到了外界的一致好评&#xff0c;上线两个月&#xff0c;获得1亿月活跃用户&#xff0c;成为增长最快的面向消费者的应用。 面对ChatGPT拟人一般的问答能力&#xff0c;很多人认为它代表着AlphaGo之后&#xff0c;人工智能应用的第二次浪潮…

电子技术——MOS差分输入对

电子技术——MOS差分输入对 差分输入系统因其极高的共模抑制能力&#xff0c;差分输入几乎是是构建所有通用模拟IC的基本前级输入&#xff0c;也是现代信号传输理论的基础。本节我们讲解MOS差分输入对。 MOS差分输入对 下图展示了MOS差分输入对的基本原理图&#xff1a; 一个…

数据采集协同架构,集成马扎克、西门子、海德汉、广数、凯恩帝、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科、华中各类数控以及各类PLC数据采集软件

文章目录 前言一、采集协同架构是什么&#xff1f;可以做什么&#xff08;数控、PLC配置采集&#xff09;&#xff1f;二、使用步骤 1.打开软件&#xff0c;配置MQTT或者数据库&#xff08;支持sqlserver、mysql等&#xff09;存储转发消息规则2.配置数控系统所采集的参数、转…

项目(今日指数)

一 项目架构1.1 今日指数技术选型【1】前端技术【2】后端技术栈【3】整体概览3.2 核心业务介绍1】业务结构预览【2】业务功能简介1.定时任务调度服务XXL-JOB通过RestTemplate多线程动态拉去股票接口数据&#xff0c;刷入数据库&#xff1b; 2.国内指数服务 3.板块指数服务 4.涨…