boruta / timebase
平面文件数据库,用于将任何数据作为时间线事件存储,并在给定的时间戳中查找。
Requires (Dev)
- phpunit/phpunit: ^9
- roave/security-advisories: dev-master
README
平面文件数据库,用于将任何数据作为时间线事件存储,并在给定的时间戳中查找。
目录
描述
数据存储在文件中,可以使用多级命名空间 - 在这种情况下,文件存储在子目录中。每天存储在一个名为 YYYY-MM-DD.tb
的单独文件中。
使用二分搜索算法搜索数据记录,因此搜索速度快,不需要将整个文件加载到内存中。每个记录是文件中的一行,格式为 {timestamp}/{data}
(data
是 base64_encode(json_encode(...))
的结果)。记录已排序,可以为单个时间戳添加多条记录 - 它们将按照添加的顺序保存和返回。
此类数据库有众多用途,例如存储股票交易所数据(成交量、价格值等)以进行交易策略回测。
要求
包需要 PHP >= 7.3 和已安装的 ext-json 扩展。
安装
使用 Composer 安装库。如果您不熟悉 Composer 或一般的依赖管理器,请阅读 Composer 文档。
composer require boruta/timebase
用法
快速介绍
创建数据库实例。第一个构造函数参数是存储数据库文件的路径。
$timebase = new Boruta\Timebase\Timebase(__DIR__ . '/database/');
插入数据(对于当前时间戳)
$timebase->insert()->set('test')->execute();
获取最后插入的数据(最后一条记录)
$result = $timebase->search()->execute();
您将得到一个数组作为结果,其键为 timestamp
和 value
array(2) { ["timestamp"]=> int(1612022907) ["value"]=> string(4) "test" }
详细信息
构造函数中的额外日志记录器
您可以可选地提供第二个参数,即一个与 Psr\Log\LoggerInterface
兼容的日志记录器对象。只有在出现错误时,应用程序才会追加日志。
$timebase = new Boruta\Timebase\Timebase(__DIR__ . '/database/', $logger);
数据类型
数据可以是任何原生类型,例如 int
、string
、array
。在搜索数据时,它们将是同一类型。
$timebase->insert() ->set(123) // or ->set('test') or ->set(['test' => 123]) etc. ->execute();
设置存储命名空间
您可以在多个级别的不同存储中存储您的数据。请使用方法 ->storage(array $storage)
来设置此选项。
将数据插入特定存储的示例
$timebase->insert() ->storage(['test']) // storage path: __DIR__ . '/database/test/' ->set('test') ->execute();
$timebase->insert() ->storage(['level0', 'level1']) // storage path: __DIR__ . '/database/level0/level1/' ->set('test') ->execute();
从特定存储读取数据的示例
$result = $timebase->search() ->storage(['test']) // storage path: __DIR__ . '/database/test/' ->execute();
$result = $timebase->search() ->storage(['level0', 'level1']) // storage path: __DIR__ . '/database/level0/level1/' ->execute();
插入特定时间戳的数据
要为给定的时间戳(不是当前时间戳)添加数据,请使用方法 ->timestamp(int $timestamp)
。示例
$timebase->insert() ->timestamp(1612022907) ->set('test') ->execute();
搜索特定时间戳的数据
在搜索查询期间使用方法 ->timestamp(int $timestamp)
来查找特定时间戳的记录
$result = $timebase->search() ->timestamp(1612022907) ->execute();
在默认策略中,您将获得与您输入的时间戳最接近的一条记录。
获取具有相同时间戳的多条记录
如果您有多个具有相同时间戳的记录,可以使用 ->all()
方法检索它们。
$result = $timebase->search() ->timestamp(1612022907) ->all() ->execute();
在结果数组中,将有一个额外的键 all
,其中包含给定时间戳的所有记录,它们的顺序与添加的顺序相同
array(3) { ["timestamp"]=> int(1612012606) ["value"]=> string(4) "test" ["all"]=> array(2) { [0]=> string(4) "test" [1]=> string(4) "test" } }
搜索策略
最近(默认)
默认策略返回与给定时间戳最接近的记录。使用方法(不是必需的,因为它是默认值)
$result = $timebase->search() ->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::NEAREST) ->timestamp(1612022907) ->execute();
如果两个记录的时间距离相同,您将得到较早的那个。
精确
如果您提供的时戳没有记录,您将得到 null
值。数据库中必须有一个与提供的时戳完全相同的记录。
$result = $timebase->search() ->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::EXACT) ->timestamp(1612022907) ->execute();
较早
如果您输入的时间戳没有记录,您将获得该时间戳之前的最近记录,或者返回null
。
$result = $timebase->search() ->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::EARLIER) ->timestamp(1612022907) ->execute();
之后
如果您输入的时间戳没有记录,您将获得该时间戳之后的最近记录,或者返回null
。
$result = $timebase->search() ->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::LATER) ->timestamp(1612022907) ->execute();
测试
要运行该包中的测试,请执行以下命令
vendor/bin/phpunit tests
一段时间后,您将得到结果,例如
OK (31 tests, 526577 assertions)