如果做一个国产数据库一链接

承接上文,继续

1、重新定义数据结构

typedef struct sdata
{uint32_t index;char vardata[128];
}sdata;typedef struct sdata_index
{uint32_t index;uint32_t offset;
}sdata_index;

sdata_index 是我们要读到一个内存里面去的,同时,我们会使用内存查找的方式,拿到数据的索引值,在内存里面使用二分查找算法

int binSearch(uint32_t x, sdata_index *a, int n)
{int low, high, mid;low = 0;high = n - 1;while (low <= high){mid = (low + high) / 2;if (x < a[mid].index)high = mid - 1;else if (x > a[mid].index)low = mid + 1;elsereturn mid;}return -1;
}

2、写入数据

修改上一文章中的写函数,数据结构,偏移量计算正确,写入文件,写入的数据在进入函数之间一定要排序

//sdata 必须是排序后数据
//2M 的索引,一半的空间为索引号码,一半的空间为数据偏移地址
//                     1024*1024/sizeof(int)
int  bfile_write(const char * file,/*uint32_t index_num,*/ sdata data[],int n)
{#define INDEX_BYTES 2 * 1024 * 1024int index_num = INDEX_BYTES / sizeof(int)*2; //max index number is 162144if (n > index_num)return -1;FILE * fp = fopen(file, "wb");if (fp == NULL)return -1;fpos_t pos_start = 0;fpos_t pos_index = 8;fpos_t pos_data = pos_index + INDEX_BYTES;fpos_t position =  4 + 4 + INDEX_BYTES + sizeof(data[0].vardata) * n;fsetpos(fp, &position);fsetpos(fp, &pos_start);//写入总索引量fwrite(&index_num, sizeof(int), 1, fp);//写入目前索引量fwrite(&n, sizeof(int), 1, fp);//排序写入文件,已经排好了序号//std::sort(&data[0], &data[n], Rule());int offsetsum = 4+4+INDEX_BYTES;int len = sizeof(data[0].vardata);for (int i = 0; i < index_num; i++){//wnum++;if (i < n){fwrite(&data[i].index, sizeof(int), 1, fp);fwrite(&offsetsum, sizeof(int), 1, fp);offsetsum += len;}else{uint64_t flag = 0;fwrite(&flag, sizeof(uint64_t), 1, fp);}}offsetsum = 4 + 4 + INDEX_BYTES;fpos_t pos = offsetsum;for (int i = 0; i < n; i++){fsetpos(fp,&pos);fwrite(&data[i].vardata, strlen(data[i].vardata), 1, fp);pos += sizeof(data[0].vardata);}fclose(fp);return 0;
}

读取数据

定义读的函数,流程为
1 、读出数据最大索引量
2 、读出数据当前记录索引量
3 、读出索引放入内存
这里并不读数据集,后面第三篇再修正读数据,放一部分数据到内存里面。

//2M的空间做索引
sdata_index* bfile_read_index(const char * file,uint32_t &num)
{size_t nr;num = 0;uint32_t indext;//索引总长度uint32_t indexn;//索引长度,内容为x个索引 indexn <= indextFILE * fp = fopen(file, "rb");if (fp == NULL)return NULL;//读取最大的index值容量nr = fread(&indext, sizeof(uint32_t), 1, fp);if (nr == 0){fclose(fp);return NULL;}//读取存储的索引值nr = fread(&indexn, sizeof(uint32_t), 1, fp);if (nr == 0){fclose(fp);return NULL;}num = indexn;//4字节索引号 4字节偏移地址uint8_t * index = (uint8_t*)malloc(indexn * sizeof(uint32_t)*2);nr = fread(index, indexn * sizeof(uint32_t) * 2, 1, fp);if (nr == 0){fclose(fp);free(index);return NULL;}return (sdata_index*)index;
}

定义从数据库中读取某一个索引值到内存中

int bfile_read(const char * file,uint32_t offset, char *buffer,size_t len)
{FILE * fp = fopen(file, "rb");fpos_t pos_start = offset;fsetpos(fp, &pos_start);size_t n =fread(buffer, sizeof(char)*len, 1, fp);fclose(fp);if (n != len)return -1;return 0;
}

4、定义主函数执行

int main()
{sdata data[100];//srand(1000);for (int i = 0; i < 100; i++){//模拟收集到的数据data[i].index = i;sprintf(data[i].vardata, "the data is %ld", data[i].index);}//std::sort(&data[0], &data[100], Rule());for (int i = 0; i < 100; i++){cout<<data[i].index<<"-->"<<data[i].vardata << endl;}bfile_write("./test.db", data, 100);uint32_t num;sdata_index *rdata =bfile_read_index("./test.db",num);cout << "the index number is " << num << endl;cout << "now read the value of index x" << endl;string s;cin>>s;int v = atoi(s.c_str());int ret = binSearch(v, rdata, num);sdata_index *p = rdata;p += ret;uint32_t offset = p->offset;char buffer[128];bfile_read("./test.db", offset, buffer, 128);cout << buffer << endl;return 0;
}

5、执行插入数据函数结果打印


查看文件已经写入

6、数据查询

输入数据查询值,如89,意思是查询第89索引的值,
首先获取内存索引中偏移量的值offset,查询的时候使用binSearch 二分查找

最后打开文件,偏移到offset处,取出拷贝里面的值,打印出 the data is 89

一个小型的数据库就这样出来了,简陋,暂时是示例,会慢慢补充起来。等待我的第三篇吧

如何做一个国产数据库(二)相关推荐

  1. 如何做一个国产数据库(七) 网络传输 java做订阅客户端

    如何做一个国产数据库一 如何做一个国产数据库二 如何做一个国产数据库三 如何做一个国产数据库四 如何做一个国产数据库五 如何做一个国产数据库六 server端协议定义 再次强调一下我们的protoco ...

  2. 如何做一个国产数据库(六) 网络传输 nodejs做测试客户端

    如何做一个国产数据库一 如何做一个国产数据库二 如何做一个国产数据库三 如何做一个国产数据库四 如何做一个国产数据库五 网络实战服务器 我们再四中说过使用tcp进行协议的链接,对我们所定义的协议如果有 ...

  3. 如何做一个国产数据库(三)

    一和二 如何做一个国产数据库一 如何做一个国产数据库二 1.数据结构重新定义 再次重新定义数据结构 typedef struct sdata {uint32_t index;char vardata[ ...

  4. 如何做一个国产数据库(四)

    网络 这次要用到网络了,存储的时候我们都使用网络来输入输出,当然,像本机是可以使用进程间通信的,不过为了简单,我们此次都使用tcp协议. 协议 此次使用libuv来做网络的传输,我们首先定一个协议,做 ...

  5. 如何做一个国产数据库系统(一)

    做国产数据库之二 做一个国产数据库 做一个数据库系统真的是要懂的是基础,各种基础,网络,文件系统,操作系统,性能,测试,各方面都要懂 使用基本方法 索引文件+数据文件+ B+ 树 ,hash空间 如图 ...

  6. 用python制作二维码_用python做一个可视化生成二维码的工具

    用python做一个可视化生成二维码的工具 环境 pip install gooey pip install MyQR 源代码 from gooey import GooeyParser,Gooey ...

  7. 练习mvc做一个知识库(二)

    上周发表了练习"mvc做一个知识库(一)".首先谢谢大家的关注,这两天有时间就看一下园子里小燕的走向ASP.NET架构设计.写的不错,对于像我这样想提高设计能力的菜鸟来说受益匪浅. ...

  8. 如何用Excel做一个战斗模拟器(二)属性表

    如何用Excel做一个战斗模拟器(一)升级经验表 如何用Excel做一个战斗模拟器(三)战斗过程模拟 目录索引 属性表 属性表 首先确定人物的生命.攻击.防御.暴击值与闪避值属性.用公式将其设定为与等 ...

  9. 如何做一个mysql数据库_如何创建一个简单的mysql数据库

    这篇文章主要介绍了操作MySQL日志的一些方法,对日志的删除操作做了重点讲解,需要的朋友可以参考下. 一.创建数据库 注:已经安装好mysql. windows下运行cmd进入命令窗口,本人用的是wi ...

最新文章

  1. 单点登录(SSO)—简介
  2. C#关于MSMQ通过HTTP远程发送专有队列消息的问题
  3. 使用sqoop将HIVE中的数据输出带Mysql中
  4. iptables端口转发命令
  5. 前端学习(2603):跨域请求的原因
  6. 简述java的线程_Java多线程的简述
  7. 收到字节 Offer,月薪 45k,揭秘面试流程及考点
  8. 13.字符串,结构,联合
  9. matmul torch 详解_python基础教程详解torch.Tensor的4种乘法
  10. 阿里云运行python_阿里云运行python代码
  11. ArcGis-学习笔记6-4 空间插值简介
  12. Windows正在配置Xftp6在下面的框输入包含安装程序包“Xftp 6.msi“的文件夹的路径
  13. Android View 获取焦点
  14. 【调剂】中科院天津工业生物技术所与天津科技大学联合培养硕士招生2023
  15. 橙色优学:互联网对传统行业说是机会,对年轻人来说更是风口
  16. 区块链10年兴衰录:中国是最好的发展土壤
  17. Linux的起源:从一个故事说起
  18. css div水平垂直居中
  19. mac之把打开终端设置快捷键为Ctrl+Alt+T
  20. 【听】你会杀死那个胖子吗?功利与道德的选择

热门文章

  1. C语言 处理字符串库 string.h
  2. 马斯克开始行动:下调Twitter Blue订阅费 禁止广告
  3. 不叫K50 Pro+!Redmi K50系列超大杯或有新名称
  4. 抖音升级老年人防沉迷提醒机制 覆盖多个使用场景
  5. 英特尔面向网络及边缘推出至强D系列处理器
  6. 一年超20万人次在抖音志愿登记器官捐献
  7. 双11即将来临,淘宝内测“购物车分享”功能
  8. 苹果蜂窝网络版iPad mini 6不支持毫米波5G
  9. 王健林最好的时代过去了
  10. 阿里巴巴招募鉴黄体验官,日薪1000元,小姐姐优先,要求阅“片”无数