在 Redis / NoSQL 或关系数据库中存储大量数据?

iKo*_*ode 3 nosql redis

我需要存储和访问金融市场烛台信息。

我需要储存的蜡烛棒数量开始变得惊人(巨大)。有 1000 个市场,每个市场都有许多交易对,每一对都有许多时间范围,每个时间范围是一组如下所示的蜡烛。例如,下面的数组可以用于每小时价格数据或每日价格数据。

我需要在任何给定时间向多个用户提供此信息,因此需要存储它并以某种方式使其可用。

数据看起来像这样:

[
    {
        time: 1528761600,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    },
    {
        time: 1528761610,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    },
    {
        time: 1528761630,
        openPrice: 100,
        closePrice: 20,
        highestPrice: 120,
        lowesetPrice:10 
    }
]
Run Code Online (Sandbox Code Playgroud)

数据的消费者将主要是一个复杂的基于 Javascript 的图表应用程序,但其他消费者将是节点代码,可能还有其他后端代码。

我目前最好的想法是将烛台保存在 Redis 中,尽管我也考虑过使用 noSQL 数据库。我在这两个方面都不是很有经验,所以我不能 100% 确定 Redis 是正确的选择。虽然它似乎是性能最高的选项,但可能更难使用,因为我必须学习很多东西,而且我不相信 Redis 使用的保存和检索方法会使这变得非常容易,因为,我需要不断地向每个数组添加蜡烛。

我目前正在考虑类似的事情:

从烛台 api 中进行初始提取,或者:

  1. 创建一个带有合适标签的 Redis 散列,并将整个蜡烛阵列插入散列,以便它返回由 Javascript 等解析

这种方法的缺点:

每次创建新蜡烛时,我都必须解析 json,添加任何新蜡烛棒并进行字符串化并保存。

这种方法的优点:

我可以使用 Javascript 来管理数组并确保它已排序等

  1. 创建一个 Redis 时间戳列表,它允许我将新蜡烛推到列表中并相信它的顺序正确。然后我可以做一个Redis SCAN吗?返回特定日期之间的时间戳,然后使用时间戳从 Redis 哈希中提取数据。在检索所有这些之后,然后构建一个类似于上面的 json 对象以传递给 Javascript。

我不得不说,这两种方法让我把数据放在关系数据库中感觉更痛苦。我想非 SQL 数据库也可以更简单,但我对它们没有经验,所以我不能肯定地说。

正如你所知道的,我有点迷失和失去了在这里的经验,并且希望任何人都可以给我任何建议。

谢谢 :)

Sri*_*nan 5

您的数据非常规则 - 每个烛台基本上都有 1 64 位长的时间戳和 4 位 32 位的价格数字。这使得它非常适合位域。

存储数据

这是我将如何存储它 -

  1. stock-symbol:daily_prices = 30 * 5 条记录的位域,假设您存储了过去 30 天的数据
  2. stock-symbol:hourly_prices = 24 * 5 条记录的位域

这样,您的内存是 (30*5 + 24*5) * 16 字节 = 每个符号 4320 字节 + 每个键的恒定开销。

您不需要存储时间戳(见下文)。另外,我假设有 4 个字节来存储价格。您可以通过消除小数将其存储为整数。

写入数据

要插入每小时价格,请查找当前小时(例如 07:00 小时)。如果将位域视为 4 字节整数数组,则必须跳过 7 * 4 = 28 个整数。然后在位置 28、29、30、31(基于 0 的索引)插入价格。

因此,要在 07:00 存储 AAPL 的价格,您可以运行以下命令

bitfield AAPL:hourly_prices set i32 28 <open price> i32 29 <close price> i32 30 <highest price> i32 31 <lowest price>

你也会对每日价格做类似的事情。

读取数据

如果您正在构建图表库,您很可能希望返回给定时间范围内多个交易品种的数据。假设您想提取过去 7 天的每日价格,您的逻辑将是 -

  1. 对于每个符号:
    1. 获取数组内的开始和结束范围
    2. 调用获取范围命令。

如果你在管道中运行它,它会非常快。

其他提示

通常,您会按符号的某些属性进行过滤。例如,“向我展示过去 5 天前 10 名科技公司的图表”。

符号本身是关系数据。我建议将其存储在关系数据库中。只需从关系数据库中以列表形式获取符号名称,然后从 redis 中获取股票价格。