FastDB简单介绍(Linux)

(本文内容主要是通过学习官网、博客及阅读官网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的抛异常的问题没有找到相关的解决方案,如果有朋友有相关解决方案,可以一起交流学习。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 最近在准备找工作,所以自己总结了一下面试题,有些来自于网上的,自己做了下整理。1、JDK 和 JRE 有什么区别?...
    走路带着风s阅读 257评论 0 1
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,085评论 0 62
  • 对于 iOS 框架的一些简单介绍 (颜色表示常用程度) Cocoa Touch GameKit 实现对游戏中心的支...
    飞奔的羊阅读 877评论 0 3
  • 一、MySQL架构与历史 A.并发控制 1.共享锁(shared lock,读锁):共享的,相互不阻塞的。 2.排...
    阿休阅读 4,638评论 0 37