FastDB简单介绍及实例(Linux)

2023-11-10

(本文内容主要是通过学习官网、博客及阅读官网demo做出的总结)

FastDB是一个内存数据库,通过把数据加载到内存中实现对数据的操作,相比于传统的数据库,操作的速度更快,但是存在一个缺点就是使用FastDB数据库的应用程序都必须运行在同一台主机上。

1 简单介绍
2 访问类型
3 使用流程
4 遇到的问题及解决办法
5 代码实例
6 总结

一、 简单介绍

1 将数据完全加载到内存,在内存中实现对数据的管理;

2 只读模式线程、单个更改模式线程和多个只读模式线程间并发执行;

3 最小单位块:分配量子(16字节);

4 事物提交协议基于一个影子根页算法,对数据库执行原子更新操作,恢复效率高;

影子根页算法:数据库中每条对象都具有唯一标识符用作一个数组(对象索引)的下标,元素值表示对象的一个句柄。(FastDB中存在两个索引:当前索引和影子索引)

5 内存数据结构组织:HASH、T树。

HASH:具有最高查找效率(不适用于插入操作中,键值冲突发生频率较高的场景);
T树:仅次于HASH(不适用于有频繁的添加、删除动作的场景);

在FastDB中,声明为HASH的KEY,采用HASH结构,声明为INDEXED的KEY采用T树结构。

二、 访问类型

1 一共四种访问类型:dbDatabase::dbReadOnly、dbDatabase::dbAllAccess、dbDatabase::dbConcurrentRead、dbDatabase::dbConcurrentUpdate;

2 FastDB不支持客户端/服务器结构(内存数据库,不能跨服务器);

3 dbDatabase::dbReadOnly:默认是这种模式;

4 dbDatabase::dbAllAccess:如果该进程使用了insert、update、delete等修改数据库的操作,其他访问该库的进程的所有操作(包括open、select)都会被阻塞,直到该操作提交或回滚。(该模式我自己在写代码时还没有用到过);

5 dbDatabase::dbConcurrentUpdate:如果某进程对数据进行修改性操作,同时另外的进程使用 dbDatabase::dbReadOnly 或者 dbDatabase::dbConcurrentRead 读数据,不会出现阻塞情况。
但是 dbDatabase::dbReadOnly 会把未提交的脏数据读出来,而dbDatabase::dbConcurrentRead不会;

6 多个进程使用 dbDatabase::dbConcurrentUpdate 实际效果和 dbDatabase::dbAllAccess 一样(阻塞);

7 不要把 dbDatabase::dbConcurrentUpdate 和 dbDatabase::dbConcurrentRead 模式混用,不能同时启动两个线程,其中一个用 dbConcurrentUpdate 模式打开数据库,另一个用 dbConcurrentRead 模式;

8 在 dbDatabase::dbConcurrentUpdate 模式下不要使用 dbDatabase::precommit方法。

三、 使用流程(Linux)

1 在fastdb官网下载安装包进行安装;

2 在服务器上安装fastdb,可以参考这个博主的文章(fastdb安装配置);

3 编写测试文件,或者直接在下载的fastdb安装包中找一个example文件进行测试;

4 编写Makefile文件,注意添加以下内容:-I/usr/local/include/fastdb -L/usr/local/lib -lrt -lz -lfastdb (上面的内容根据自己的实际安装路径进行调整)。

5 编译代通过,运行代码。

四、 遇到的问题及解决办法

1 undefined reference to dbDatabase::~ 等报错

原因 :没有成功引入相关的头文件或者.so文件;

解决办法:编写Makefile文件时没有添加相关的依赖(参考上面的第4点内容);

2 Incompatibility between headers and library:6 vs. 4

原因:fastdb会假设绝大多数Linux是64-bit的,如果测试的是32-bit的,就会报错;

解决办法:根据安装目录,找到fastdb目录下的config.h头文件,将以下代码注释即可。(运行的环境是64-bit的,依旧报错,感觉不是这个原因,但是按照这种方法可以解决,很迷~)

//#if!defined(_WIN32)||defined(_WIN64)//most unixes are now 64-bit,while 32-bit windows is still quite popular
//#define LARGE_DATABASE_SUPPORT
//#endif

3 当运行的数据大概达到一千万条以上的时候,即生成的文件内容达到2G之后,程序就会抛出异常,自动停止,这个问题找了很久一直也没有解决。

五、 代码实例

下面的代码只是一个简单的实例,包含了表关联(删除一个表的数据,另一个表相关的记录也会被删除),数组的使用,插入数据、查询数据、删除数据。

(ps:下面的代码是手撕的(不是copy的服务器上面的代码),没有实际测过,可能会有一些小小的问题,欢迎指出,不过大体上是没有什么问题的。)

#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include "fastdb.h"
#include "database.h"
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
#include <sring>

using namespace std;
USE_FASTDB_NAMESPACE

dbDatabase db;

#define random(a,b) (rand()%(b-a))+a+1  //生成随机数
#define TeacherNum 5   //老师个数
#define StudentNum 20  //学生个数

class Student;
class Teacher
{
public:
	const char* teacher_name;
	dbArray<dbReference<Student>> std_code;
	TYPE_DESCRIPTOR((KEY(teacher_name,INDEXED),OWNER(std_code,tech_code)));
};

class Student
{
public:
	const char* std_name;
	dbArray<int4> scores;  //Chinese English Math
	dbReference<Teacher> tech_code;
	TYPE_DESCRIPTOR((KEY(std_name,INDEXED),
					 FIELD(scores),
					 RELATION(tech_code,std_code)));

};

REGISTER(Teacher);  //注册Teacher表
REGISTER(Student);  //注册Student表

//生成老师的编号
void getRandomCharTeach(char * randnum)
{
	int num = random(0,10);  
	snprintf(randnum,sizeof(randnum),"%d",num);  //int类型转换为char *
}

//生成学生的编号
void getRandomCharStu(char * randnum)
{
	int num = random(20,50);
	snprintf(randnum,sizeof(randnum),"%d",num);  //int类型转换为char *
}

//生成0-100之间的随机数
int4 getRandomIntSocre()
{
	int num = random(0,100);
	return num;
}

//查询老师编号
void selectTeachName()
{
	cout<<"***** selectTeachName *****"<<endl;
	dbCursor<Teacher> cursorTeach;  //只读游标
	int n = cursorTeach.select();  //查询
	cout<<"Teacher的数量为:"<<n<<endl;

	if(0<n)
	{
		do
		{
			cout<<"teacher_name = "<<cursorTeach->teacher_name<<" ."<<endl;
		}while(cursorTeach.next());  //游标向后滚
	}
}

//查询学生信息
void selectStuInfo()
{
	cout<<"***** selectStuInfo *****"<<endl;
	dbCursor<Student> cursorStu;  //只读游标
	int n = cursorStu.select();  //查询
	cout<<"Student的数量为:"<<n<<endl;

	if(0<n)
	{
		do
		{
			cout<<"std_name = "<<cursorStu->std_name<<" , "<<
			"Chinese = "<<cursorStu->scores[0]<<" , "<<
			"English = "<<cursorStu->scores[1]<<" , "<<
			"Math = "<<cursorStu->scores[2]<<" ."<<endl;
		}while(cursorStu.next());  //游标向后滚
	}
}

//删除所有数据
void removeAllRecord()
{
	cout<<"***** removeAllRecord *****"<<endl;
	dbCursor<Teacher> cursorTeach(dbCursorForUpdate);  //写游标对象
	cursorTeach.removeAll();
	dbCursor<Student> cursorStu(dbCursorForUpdate);  //写游标对象
	cursorStu.removeAll();
}


int main()
{
	Teacher techer;
	Student student;

	if(db.open(_T("test")))
	{
		cout<<"Start inserting data..."<<endl;
		for(int i = 0; i < TeacherNum; i++)
		{
			char tech_num[2];
			getRandomCharTeach(tech_num);
			techer.teacher_name = tech_num;
			dbReference<Teacher> techer_class = insert(techer);
			cout<<"Insert "<<techer.teacher_name<<" to Teacher."<<endl;
			db.commit();

			//插入多个学生信息对应当前老师
			for(int j = 0; j < StudentNum; j++)
			{
				char std_num[2];
				getRandomCharStu(std_num);
				student.std_name = std_num;
				int Chinese = getRandomIntSocre();  //语文成绩
				int English = getRandomIntSocre();  //英语成绩
				int Math = getRandomIntSocre();  //数学成绩
				
				student.scores(3);  //数组大小为3
				student.scores.putat(0,Chinese);  //把各科成绩放到数组中
				student.scores.putat(1,English);
				student.scores.putat(2,Math);
				student.tech_code = techer_class;  //把当前学生的信息与对应老师相关联
				insert(student);  
				cout<<"Insert std_name : "<<student.std_name<<" , "<<
				"Chinese : "<<Chinese<<" , "<<
				"English : "<<English<<" , "<<
				"Math : "<<Math<<" ."<<endl;
			}
			db.commit();
		}
		//查询、删除的实例可以在open表之后直接调就可以了,这里就不写了
	}
	db.commit();
	return 0;
}

六、 总结

fastDB确地有它的优点,但是现有的相关资料比较少,所以使用起来会有难度,重点是文件超过2G的抛异常的问题没有找到相关的解决方案,如果有朋友有相关解决方案,可以一起交流学习。

----------如有侵权,联系删除!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastDB简单介绍及实例(Linux) 的相关文章

  • 将集合绑定到自定义控件属性

    我没有运气尝试将数据集合绑定到我的自定义控件的属性 我已经实现了该控件的字符串属性的机制 在此处提供了一些帮助 并期望集合类型同样简单 但是我无法让它再次工作 这是我的自定义控件视图
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • 将 char[][] 转换为 char** 会导致段错误吗?

    好吧 我的 C 有点生疏了 但我想我应该用 C 来做我的下一个 小 项目 这样我就可以对其进行抛光 并且我已经有不到 20 行的段错误了 这是我的完整代码 define ROWS 4 define COLS 4 char main map
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • 快手开店怎么引流?快手小店自上线以来就吸引众多的商家入驻

    快手开店怎么引流 快手小店自上线以来就吸引众多的商家入驻 快手小店自上线以来就吸引众多的商家入驻 当然也有不少快手主播粉丝多了也会去卖货多赚点钱 在快手上面开店重视的还是流量 如何才能给店铺带来更多的流量呢 商家需要怎么做 下面一起来看快手
  • 程序员模式

    在我的心中 程序员是一个做事有计划 有思想 具有高超技术 解决能力的艺术家 自己作为一个程序员 自愧不能达到如上的标准 看到过一个程序员曾经这样自嘲 一个只有半瓶子水晃晃荡荡的程序员 这些年来一直从事开发的工作 稀里糊涂跑过许多城市 流浪过
  • Oracle环境变量配置步骤

    Oracle11g环境变量配置 在做开发的过程中 几次重装系统安装配置过Oracle 本篇博客就对oracle配置环境变量的细节做一次记录和分享 三个模块 Oracle11g的安装 instantclient 11 2客户端的安装 PLSQ
  • waiting for ZeroTier system service,

    查了好几个回答 waiting for ZeroTier system service这个错误是之前装过但是卸载后未删除干净造成的 我是卸载后删除了下边四个路径下的Zero Tier文件夹 然后重装就好了 Program Files Pro
  • Elasticsearch7.17 四 : ElasticSearch集群架构

    文章目录 ElasticSearch集群架构 核心概念 节点 分片 Primary Shard Replica Shard 集群状态和分片设定 集群搭建 安装Cerebro客户端 安装kibana ES安全认证 集群内部安全通信 开启并配置
  • Wireshark应用

    1 过滤IP 如来源IP或者目标IP等于某个IP 例子 ip src eq 192 168 1 107 or ip dst eq 192 168 1 107 或者 ip addr eq 192 168 1 107 都能显示来源IP和目标IP
  • ecshop缓存清理-限制或禁用ECShop缓存

    ECSHOP的缓存存放在templates caches 文章夹下 时间长了这个文件夹就会非常庞大 拖慢网站速度 还有很多情况我们不需要他的缓存 本文介绍禁用ECSHOP缓存的方法 ECSHOP的缓存有两部分 一部分是SMARTY的页面缓存
  • Unity 获取UI(RectTransform)四个角的屏幕坐标

    获取UI RectTransform 四个角的屏幕坐标 Vector3 corners new Vector3 4
  • oj2016: C语言实验——打印金字塔

    问题描述 输入n值 打印下列形状的金字塔 其中n代表金字塔的层数 作者 何知令 发表时间 2017年2月23日4 输入 输入只有一个正整数n 输出 打印金字塔图形 其中每个数字之间有一个空格 代码 问题描述 输入n值 打印下列形状的金字塔
  • 小m序列的verilog实现

    verilog实现及仿真 m sequence v 以x8 x4 x3 x2 1为例 module m sequence input sclk input rst n output wire m seq parameter POLY 8 b
  • 【每日一题】补档 ABC309F - Box in Box

    题目内容 原题链接 给定 n n n 个箱子 问是否存在一个箱子 x x x 是否可以放到另一个箱子 y
  • Java简单实现斗地主洗牌、发牌功能

    需求 在启动游戏房间的时候 应该提前准备好54张牌 完成洗牌 发牌 牌排序 逻辑 分析 当系统启动的同时需要准备好数据的时候 就可以用静态代码块了 洗牌就是打乱牌的顺序 定义三个玩家 依次发出51张牌 给玩家的牌进行排序 拓展 输出每个玩家
  • 如何编写测试用例?流程及5大编写步骤

    编写测试用例的5个步骤 1 选择测试工具 2 确定测试场景 3 编写测试用例 4 确认测试用例 5 组织测试用例 但在编写测试用例之前 测试人员需要充分了解软件的需求和规格 以确保测试用例能够覆盖所有的功能和场景 测试用例是一种用于验证软件
  • python 【组成最大数】

    组成最大数 小组中每位都有一张卡片 卡片上是6位内的正整数 将卡片连起来可以组成多种数字 计算组成的最大数字 输入描述 号分割的多个正整数字符串 不需要考虑非数字异常情况 小组最多25个人 输出描述 最大的数字字符串 示例1 输入 22 2
  • 2023年武汉市中等职业学校技能大赛 “网络搭建与应用”

    2023年武汉市中等职业学校技能大赛 网络搭建与应用 一 竞赛内容分布 网络搭建及应用 竞赛共分二个部分 其中 第一部分 企业网络搭建部署项目 占总分的比例为50 第二部分 企业网络服务配置及应用项目 占总分的比例为50 项目背景及网络拓扑
  • OpenCV函数cvWaitKey(k)简介

    作者本人的开发环境为VS的MFC构架 结合OpenCV1 0进行图像的处理 可能很多像作者本人一样的初始开发程序员都会用到cvWaitKey 但是对cvWaitKey 的理解一知半解 在具体开发中会由此产生一些困惑 在查询了一些资料后 将资
  • Java实现文件分片上传

    为什么需要文件分片上传 大文件上传中断 假如我们有一个5G的文件 上传过程中突然中断我们该怎么办 上文件上传响应时间长 假如我们有个10G的文件 单次上传时间长 用户体验长 该怎么办 大文件上传重复上传 某些大文件 我们已经上传过了 我们不
  • JavaScript基础知识总结(6张思维导图)

    以下导图均为学习pink老师js基础视频时 自主整理的 有不足的地方 欢迎大家多多指出
  • 如何正确的进行网站入侵渗透测试

    大家都知道渗透测试就是为了证明网络防御按照预期计划正常运行而提供的一种机制 而且够独立地检查你的网络策略 一起来看看网站入侵渗透测试的正确知识吧 简单枚举一些渗透网站一些基本常见步骤 一 信息收集 要检测一个站首先应先收集信息如whois信
  • FastDB简单介绍及实例(Linux)

    本文内容主要是通过学习官网 博客及阅读官网demo做出的总结 FastDB是一个内存数据库 通过把数据加载到内存中实现对数据的操作 相比于传统的数据库 操作的速度更快 但是存在一个缺点就是使用FastDB数据库的应用程序都必须运行在同一台主