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

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

首先,假设我们的记录数据为:记录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,这样我们就能访问该记录了,根据块索引,我们就能找到块的起始地址,再读出该块,然后根据索引就能访问到该记录了,下图是上图介绍的记录文件的文件组织结构。

定长记录采用数据库读写并非最佳解决方案_第1张图片

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

你可能感兴趣的:(定长记录采用数据库读写并非最佳解决方案)