我需要将一些数据存储在一个文件中.每个记录(数据集)包括:
将所有这些东西保存在二进制文件中并不困难.但是,我确信(不幸的是)我的数据格式会随时间发生变化,我希望有可能为每个"记录"添加更多字段.所以,显然我的文件格式无法修复.我想最好的解决方案是将数据保存在(DB)表中,但我不想搞砸大枪(SQL,ADO,BDE,Nexus ......).我需要一个可以做到这一点的基础库(如果可能的话,单个PAS文件).由于这样做的目的是存储数据而不是处理数据,是否可以在没有DB表的情况下完成?
该库的要求:
我用的是D7
Arn*_*hez 10
看看我们的Synopse Big Table单元.
通过最近的升级,它可以完全满足您的需求.
以下是创建字段布局的方法:
var Table: TSynBigTableRecord;
FieldText, FieldInt: TSynTableFieldProperties;
begin
Table := TSynBigTableRecord.Create('FileName.ext','TableName');
FieldText := Table.AddField('text',tftWinAnsi,[tfoIndex]);
FieldInt := Table.AddField('Int',tftInt32,[tfoIndex,tfoUnique]);
Table.AddFieldUpdate;
Run Code Online (Sandbox Code Playgroud)
要存储一个字节或整数数组,只需使用tftWinAnsi甚至更好tftBlobInternal的字段(这是一个真正的可变长度字段),然后将其映射到动态数组或从动态数组映射,就像一个RawByteString.
您可以安全地稍后添加字段,将为您处理数据文件.
有几种处理数据的方法,但我已经实现了一种基于变体的使用记录的方式,具有真正的后期绑定:
var vari: Variant;
// initialize the variant
vari := Table.VariantVoid;
// create record content, and add it to the database
vari.text := 'Some text';
vari.int := 12345;
aID := Table.VariantAdd(vari);
if aID=0 then
ShowMessage('Error adding record');
// how to retrieve it
vari := Table.VariantGet(aID);
assert(vari.ID=aID);
assert(vari.INT=12345);
assert(vari.Text='Some text');
Run Code Online (Sandbox Code Playgroud)
关于速度,你找不到更快的恕我直言.使用一些文本和整数值创建1,000,000条记录,使用索引的两个字段和设置为唯一的整数字段在我的笔记本电脑上小于880毫秒.它将使用非常少的磁盘空间,因为所有存储都是可变长度编码的(类似于Google的协议缓冲区).
它只需要两个单元,适用于Delphi 6到XE(并且已准备好Unicode,因此使用此单元可以在需要时安全地升级到更新的Delphi版本).没有安装需求,只有几KB添加到您的可执行文件中.它只是一个用纯Delphi编写的小而强大的NoSQL引擎,但具有使用数据库的能力(即纯字段布局)和内存引擎的速度,没有大小限制.
它是完整的OpenSource,具有许可许可.
请注意,我们还提供了一个SQLite3包装器,但它是另一个项目.SQL支持和集成的客户端/服务器ORM,速度更慢但功能更强大.
我认为您不需要为此建立数据库。如果您使用数据库,我不知道它如何解决数据结构更改的问题。
我个人会存储为 YAML 格式,这种格式非常容易扩展。这需要链接到某些 LIBYAML 进行大量工作,因此一个非常轻量级的替代方案是存储到 INI 文件。这些很容易扩展,同时保持与旧文件的兼容性。
您可以非常轻松地推出自己的可扩展二进制格式。您所做的是将每条记录写入一个块。每个块都有一个短标头,其中包含其长度。
当您读取数据时,您会读到块的末尾,然后如果您期望更多数据,您只需停止读取并使用数据的默认值即可。如果您已阅读了您所知道的所有数据,但不在块的末尾,则该文件一定来自程序的较新版本,您只需跳到块的末尾即可。也许您警告该文件包含您不知道的数据。
可扩展性是通过始终按照与以前版本相同的顺序写出数据来实现的。任何新数据都位于每个块的末尾。