定长记录采用数据库读写并非最佳解决方案

对于有些应用场合如仪器仪表的采样数据,不需要对数据排序、插入和修改,只需要对数据写和读操作,在这种情况下,使用数据库来存取这样的记录数据,未必是最佳的选择,本文根据工作实践,采用文件的分块记录的方法,来处理采样这样的定长记录数据,实践证明,通过文件的分块存储方法,比数据库存储方法读写速度更快,尤其是在处理大批量的记录数据的读写的时候,这种速度上的优势更为显著。下面是分块记录的具体实现方法:

首先,假设我们的记录数据为:记录id号,电流,电压,温度,电阻,用结构体表示为:

typedef struct tagRecord {
quint64 id;
float cur;
float vol;
float tempe;
float resistor;
} Trecord;

那么我们怎么用文件的方式来记录上述数据呢?把文件记录划分为3个部分,文件头,索引块,记录块。

1文件头

typedef struct tagFileHead {
quint8 magic[MAGIC_LEN];
quint32 version;
quint32 indexBlkNum;
} TFileHead;

(1)magic说明文件是记录文件,这样方便解析,当文件的开头不是magic时,说明这个不是我的文件格式

(2)version方便扩展

(3)indexBlkNum,这个后面会讲,先放一放

2.索引块

typedef struct tagBlkHead {
quint64 nextBlkPos;
quint32 recordNum;
}TBlkHead;

typedef struct tagIndexBlk {
TBlkHead head;
quint32 blkAddr[INDEX_BLK_RECORD_NUM];
} TIndexBlk;

索引块是为了方便记录块的读取而引入的,由两部分组成,块头,nextBlkPos保存当前索引块的下一块位置,recordNum当前索引块的有效记录数,索引块的最大记录数为INDEX_BLK_RECORD_NUM;blkAddr,存放记录块的起始地址。这样的话,在读记录的时候,首先根据索引块建立一个记录块的索引,比如INDEX_BLK_RECORD_NUM = 1000,假如记录块数<1000,那么这样我只需要读1次文件,就可以知道所有记录块的起始地址,有了每个记录块的起始地址,由于记录块记录数也是定值,这样的话,我要访问文件中的任1条记录,只需要读文件1次,从而不管文件的大小,访问文件中的任意1条记录都只需读文件1次。
3.记录块

typedef struct tagRecordBlk {
TBlkHead blkHead;
TRecord record[RECORD_BLK_RECORD_NUM];
} TRecordBlk;

blkHead同上,record这是我们要保存的数据,我们要访问记录号为id的记录,那应怎么访问呢?

int blkIndex = id / RECORD_BLK_RECORD_NUM;
int blkOffset = id % RECORD_BLK_RECORD_NUM;

只需根据上式先算出该记录在那一块blkIndex,再算出该记录在块中的偏移blkOffset,这样我们就能访问该记录了,根据块索引,我们就能找到块的起始地址,再读出该块,然后根据索引就能访问到该记录了,下图是上图介绍的记录文件的文件组织结构。



 好了今天就写到这里了,明天写实现方式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RabinSong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值