boruta/timebase

平面文件数据库,用于将任何数据作为时间线事件存储,并在给定的时间戳中查找。

0.1 2021-01-30 17:39 UTC

This package is auto-updated.

Last update: 2024-09-29 05:43:06 UTC


README

Tests Status

平面文件数据库,用于将任何数据作为时间线事件存储,并在给定的时间戳中查找。

目录

  1. 描述
  2. 要求
  3. 安装
  4. 用法
    1. 快速介绍
    2. 详细信息
      1. 构造函数中的额外日志记录器
      2. 数据类型
      3. 设置存储命名空间
      4. 插入特定时间戳的数据
      5. 搜索特定时间戳的数据
      6. 获取具有相同时间戳的多条记录
      7. 搜索策略
  5. 测试

描述

数据存储在文件中,可以使用多级命名空间 - 在这种情况下,文件存储在子目录中。每天存储在一个名为 YYYY-MM-DD.tb 的单独文件中。

使用二分搜索算法搜索数据记录,因此搜索速度快,不需要将整个文件加载到内存中。每个记录是文件中的一行,格式为 {timestamp}/{data} (database64_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();

您将得到一个数组作为结果,其键为 timestampvalue

array(2) {
  ["timestamp"]=>
  int(1612022907)
  ["value"]=>
  string(4) "test"
}

详细信息

构造函数中的额外日志记录器

您可以可选地提供第二个参数,即一个与 Psr\Log\LoggerInterface 兼容的日志记录器对象。只有在出现错误时,应用程序才会追加日志。

$timebase = new Boruta\Timebase\Timebase(__DIR__ . '/database/', $logger);

数据类型

数据可以是任何原生类型,例如 intstringarray。在搜索数据时,它们将是同一类型。

$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)